diff options
Diffstat (limited to 'scripts/mod')
-rw-r--r-- | scripts/mod/file2alias.c | 57 | ||||
-rw-r--r-- | scripts/mod/modpost.c | 159 |
2 files changed, 151 insertions, 65 deletions
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 220213e603db..5758aab0d8bb 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c | |||
@@ -796,6 +796,51 @@ static int do_platform_entry(const char *filename, | |||
796 | return 1; | 796 | return 1; |
797 | } | 797 | } |
798 | 798 | ||
799 | static int do_mdio_entry(const char *filename, | ||
800 | struct mdio_device_id *id, char *alias) | ||
801 | { | ||
802 | int i; | ||
803 | |||
804 | alias += sprintf(alias, MDIO_MODULE_PREFIX); | ||
805 | |||
806 | for (i = 0; i < 32; i++) { | ||
807 | if (!((id->phy_id_mask >> (31-i)) & 1)) | ||
808 | *(alias++) = '?'; | ||
809 | else if ((id->phy_id >> (31-i)) & 1) | ||
810 | *(alias++) = '1'; | ||
811 | else | ||
812 | *(alias++) = '0'; | ||
813 | } | ||
814 | |||
815 | /* Terminate the string */ | ||
816 | *alias = 0; | ||
817 | |||
818 | return 1; | ||
819 | } | ||
820 | |||
821 | /* Looks like: zorro:iN. */ | ||
822 | static int do_zorro_entry(const char *filename, struct zorro_device_id *id, | ||
823 | char *alias) | ||
824 | { | ||
825 | id->id = TO_NATIVE(id->id); | ||
826 | strcpy(alias, "zorro:"); | ||
827 | ADD(alias, "i", id->id != ZORRO_WILDCARD, id->id); | ||
828 | return 1; | ||
829 | } | ||
830 | |||
831 | /* looks like: "pnp:dD" */ | ||
832 | static int do_isapnp_entry(const char *filename, | ||
833 | struct isapnp_device_id *id, char *alias) | ||
834 | { | ||
835 | sprintf(alias, "pnp:d%c%c%c%x%x%x%x*", | ||
836 | 'A' + ((id->vendor >> 2) & 0x3f) - 1, | ||
837 | 'A' + (((id->vendor & 3) << 3) | ((id->vendor >> 13) & 7)) - 1, | ||
838 | 'A' + ((id->vendor >> 8) & 0x1f) - 1, | ||
839 | (id->function >> 4) & 0x0f, id->function & 0x0f, | ||
840 | (id->function >> 12) & 0x0f, (id->function >> 8) & 0x0f); | ||
841 | return 1; | ||
842 | } | ||
843 | |||
799 | /* Ignore any prefix, eg. some architectures prepend _ */ | 844 | /* Ignore any prefix, eg. some architectures prepend _ */ |
800 | static inline int sym_is(const char *symbol, const char *name) | 845 | static inline int sym_is(const char *symbol, const char *name) |
801 | { | 846 | { |
@@ -943,6 +988,18 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, | |||
943 | do_table(symval, sym->st_size, | 988 | do_table(symval, sym->st_size, |
944 | sizeof(struct platform_device_id), "platform", | 989 | sizeof(struct platform_device_id), "platform", |
945 | do_platform_entry, mod); | 990 | do_platform_entry, mod); |
991 | else if (sym_is(symname, "__mod_mdio_device_table")) | ||
992 | do_table(symval, sym->st_size, | ||
993 | sizeof(struct mdio_device_id), "mdio", | ||
994 | do_mdio_entry, mod); | ||
995 | else if (sym_is(symname, "__mod_zorro_device_table")) | ||
996 | do_table(symval, sym->st_size, | ||
997 | sizeof(struct zorro_device_id), "zorro", | ||
998 | do_zorro_entry, mod); | ||
999 | else if (sym_is(symname, "__mod_isapnp_device_table")) | ||
1000 | do_table(symval, sym->st_size, | ||
1001 | sizeof(struct isapnp_device_id), "isa", | ||
1002 | do_isapnp_entry, mod); | ||
946 | free(zeros); | 1003 | free(zeros); |
947 | } | 1004 | } |
948 | 1005 | ||
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 20923613467c..f6127b9f5aca 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
@@ -503,6 +503,11 @@ static int ignore_undef_symbol(struct elf_info *info, const char *symname) | |||
503 | strncmp(symname, "_rest32gpr_", sizeof("_rest32gpr_") - 1) == 0 || | 503 | strncmp(symname, "_rest32gpr_", sizeof("_rest32gpr_") - 1) == 0 || |
504 | strncmp(symname, "_save32gpr_", sizeof("_save32gpr_") - 1) == 0) | 504 | strncmp(symname, "_save32gpr_", sizeof("_save32gpr_") - 1) == 0) |
505 | return 1; | 505 | return 1; |
506 | if (info->hdr->e_machine == EM_PPC64) | ||
507 | /* Special register function linked on all modules during final link of .ko */ | ||
508 | if (strncmp(symname, "_restgpr0_", sizeof("_restgpr0_") - 1) == 0 || | ||
509 | strncmp(symname, "_savegpr0_", sizeof("_savegpr0_") - 1) == 0) | ||
510 | return 1; | ||
506 | /* Do not ignore this symbol */ | 511 | /* Do not ignore this symbol */ |
507 | return 0; | 512 | return 0; |
508 | } | 513 | } |
@@ -781,10 +786,13 @@ static void check_section(const char *modname, struct elf_info *elf, | |||
781 | #define ALL_EXIT_TEXT_SECTIONS \ | 786 | #define ALL_EXIT_TEXT_SECTIONS \ |
782 | ".exit.text$", ".devexit.text$", ".cpuexit.text$", ".memexit.text$" | 787 | ".exit.text$", ".devexit.text$", ".cpuexit.text$", ".memexit.text$" |
783 | 788 | ||
784 | #define ALL_INIT_SECTIONS INIT_SECTIONS, DEV_INIT_SECTIONS, \ | 789 | #define ALL_XXXINIT_SECTIONS DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, \ |
785 | CPU_INIT_SECTIONS, MEM_INIT_SECTIONS | 790 | MEM_INIT_SECTIONS |
786 | #define ALL_EXIT_SECTIONS EXIT_SECTIONS, DEV_EXIT_SECTIONS, \ | 791 | #define ALL_XXXEXIT_SECTIONS DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, \ |
787 | CPU_EXIT_SECTIONS, MEM_EXIT_SECTIONS | 792 | MEM_EXIT_SECTIONS |
793 | |||
794 | #define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS | ||
795 | #define ALL_EXIT_SECTIONS EXIT_SECTIONS, ALL_XXXEXIT_SECTIONS | ||
788 | 796 | ||
789 | #define DATA_SECTIONS ".data$", ".data.rel$" | 797 | #define DATA_SECTIONS ".data$", ".data.rel$" |
790 | #define TEXT_SECTIONS ".text$" | 798 | #define TEXT_SECTIONS ".text$" |
@@ -814,33 +822,29 @@ static const char *data_sections[] = { DATA_SECTIONS, NULL }; | |||
814 | 822 | ||
815 | 823 | ||
816 | /* symbols in .data that may refer to init/exit sections */ | 824 | /* symbols in .data that may refer to init/exit sections */ |
817 | static const char *symbol_white_list[] = | 825 | #define DEFAULT_SYMBOL_WHITE_LIST \ |
818 | { | 826 | "*driver", \ |
819 | "*driver", | 827 | "*_template", /* scsi uses *_template a lot */ \ |
820 | "*_template", /* scsi uses *_template a lot */ | 828 | "*_timer", /* arm uses ops structures named _timer a lot */ \ |
821 | "*_timer", /* arm uses ops structures named _timer a lot */ | 829 | "*_sht", /* scsi also used *_sht to some extent */ \ |
822 | "*_sht", /* scsi also used *_sht to some extent */ | 830 | "*_ops", \ |
823 | "*_ops", | 831 | "*_probe", \ |
824 | "*_probe", | 832 | "*_probe_one", \ |
825 | "*_probe_one", | 833 | "*_console" |
826 | "*_console", | ||
827 | NULL | ||
828 | }; | ||
829 | 834 | ||
830 | static const char *head_sections[] = { ".head.text*", NULL }; | 835 | static const char *head_sections[] = { ".head.text*", NULL }; |
831 | static const char *linker_symbols[] = | 836 | static const char *linker_symbols[] = |
832 | { "__init_begin", "_sinittext", "_einittext", NULL }; | 837 | { "__init_begin", "_sinittext", "_einittext", NULL }; |
833 | 838 | ||
834 | enum mismatch { | 839 | enum mismatch { |
835 | NO_MISMATCH, | 840 | TEXT_TO_ANY_INIT, |
836 | TEXT_TO_INIT, | 841 | DATA_TO_ANY_INIT, |
837 | DATA_TO_INIT, | 842 | TEXT_TO_ANY_EXIT, |
838 | TEXT_TO_EXIT, | 843 | DATA_TO_ANY_EXIT, |
839 | DATA_TO_EXIT, | 844 | XXXINIT_TO_SOME_INIT, |
840 | XXXINIT_TO_INIT, | 845 | XXXEXIT_TO_SOME_EXIT, |
841 | XXXEXIT_TO_EXIT, | 846 | ANY_INIT_TO_ANY_EXIT, |
842 | INIT_TO_EXIT, | 847 | ANY_EXIT_TO_ANY_INIT, |
843 | EXIT_TO_INIT, | ||
844 | EXPORT_TO_INIT_EXIT, | 848 | EXPORT_TO_INIT_EXIT, |
845 | }; | 849 | }; |
846 | 850 | ||
@@ -848,6 +852,7 @@ struct sectioncheck { | |||
848 | const char *fromsec[20]; | 852 | const char *fromsec[20]; |
849 | const char *tosec[20]; | 853 | const char *tosec[20]; |
850 | enum mismatch mismatch; | 854 | enum mismatch mismatch; |
855 | const char *symbol_white_list[20]; | ||
851 | }; | 856 | }; |
852 | 857 | ||
853 | const struct sectioncheck sectioncheck[] = { | 858 | const struct sectioncheck sectioncheck[] = { |
@@ -857,80 +862,103 @@ const struct sectioncheck sectioncheck[] = { | |||
857 | { | 862 | { |
858 | .fromsec = { TEXT_SECTIONS, NULL }, | 863 | .fromsec = { TEXT_SECTIONS, NULL }, |
859 | .tosec = { ALL_INIT_SECTIONS, NULL }, | 864 | .tosec = { ALL_INIT_SECTIONS, NULL }, |
860 | .mismatch = TEXT_TO_INIT, | 865 | .mismatch = TEXT_TO_ANY_INIT, |
866 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
861 | }, | 867 | }, |
862 | { | 868 | { |
863 | .fromsec = { DATA_SECTIONS, NULL }, | 869 | .fromsec = { DATA_SECTIONS, NULL }, |
864 | .tosec = { ALL_INIT_SECTIONS, NULL }, | 870 | .tosec = { ALL_XXXINIT_SECTIONS, NULL }, |
865 | .mismatch = DATA_TO_INIT, | 871 | .mismatch = DATA_TO_ANY_INIT, |
872 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
873 | }, | ||
874 | { | ||
875 | .fromsec = { DATA_SECTIONS, NULL }, | ||
876 | .tosec = { INIT_SECTIONS, NULL }, | ||
877 | .mismatch = DATA_TO_ANY_INIT, | ||
878 | .symbol_white_list = { | ||
879 | "*_template", "*_timer", "*_sht", "*_ops", | ||
880 | "*_probe", "*_probe_one", "*_console", NULL | ||
881 | }, | ||
866 | }, | 882 | }, |
867 | { | 883 | { |
868 | .fromsec = { TEXT_SECTIONS, NULL }, | 884 | .fromsec = { TEXT_SECTIONS, NULL }, |
869 | .tosec = { ALL_EXIT_SECTIONS, NULL }, | 885 | .tosec = { ALL_EXIT_SECTIONS, NULL }, |
870 | .mismatch = TEXT_TO_EXIT, | 886 | .mismatch = TEXT_TO_ANY_EXIT, |
887 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
871 | }, | 888 | }, |
872 | { | 889 | { |
873 | .fromsec = { DATA_SECTIONS, NULL }, | 890 | .fromsec = { DATA_SECTIONS, NULL }, |
874 | .tosec = { ALL_EXIT_SECTIONS, NULL }, | 891 | .tosec = { ALL_EXIT_SECTIONS, NULL }, |
875 | .mismatch = DATA_TO_EXIT, | 892 | .mismatch = DATA_TO_ANY_EXIT, |
893 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
876 | }, | 894 | }, |
877 | /* Do not reference init code/data from devinit/cpuinit/meminit code/data */ | 895 | /* Do not reference init code/data from devinit/cpuinit/meminit code/data */ |
878 | { | 896 | { |
879 | .fromsec = { DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, MEM_INIT_SECTIONS, NULL }, | 897 | .fromsec = { ALL_XXXINIT_SECTIONS, NULL }, |
880 | .tosec = { INIT_SECTIONS, NULL }, | 898 | .tosec = { INIT_SECTIONS, NULL }, |
881 | .mismatch = XXXINIT_TO_INIT, | 899 | .mismatch = XXXINIT_TO_SOME_INIT, |
900 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
882 | }, | 901 | }, |
883 | /* Do not reference cpuinit code/data from meminit code/data */ | 902 | /* Do not reference cpuinit code/data from meminit code/data */ |
884 | { | 903 | { |
885 | .fromsec = { MEM_INIT_SECTIONS, NULL }, | 904 | .fromsec = { MEM_INIT_SECTIONS, NULL }, |
886 | .tosec = { CPU_INIT_SECTIONS, NULL }, | 905 | .tosec = { CPU_INIT_SECTIONS, NULL }, |
887 | .mismatch = XXXINIT_TO_INIT, | 906 | .mismatch = XXXINIT_TO_SOME_INIT, |
907 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
888 | }, | 908 | }, |
889 | /* Do not reference meminit code/data from cpuinit code/data */ | 909 | /* Do not reference meminit code/data from cpuinit code/data */ |
890 | { | 910 | { |
891 | .fromsec = { CPU_INIT_SECTIONS, NULL }, | 911 | .fromsec = { CPU_INIT_SECTIONS, NULL }, |
892 | .tosec = { MEM_INIT_SECTIONS, NULL }, | 912 | .tosec = { MEM_INIT_SECTIONS, NULL }, |
893 | .mismatch = XXXINIT_TO_INIT, | 913 | .mismatch = XXXINIT_TO_SOME_INIT, |
914 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
894 | }, | 915 | }, |
895 | /* Do not reference exit code/data from devexit/cpuexit/memexit code/data */ | 916 | /* Do not reference exit code/data from devexit/cpuexit/memexit code/data */ |
896 | { | 917 | { |
897 | .fromsec = { DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, MEM_EXIT_SECTIONS, NULL }, | 918 | .fromsec = { ALL_XXXEXIT_SECTIONS, NULL }, |
898 | .tosec = { EXIT_SECTIONS, NULL }, | 919 | .tosec = { EXIT_SECTIONS, NULL }, |
899 | .mismatch = XXXEXIT_TO_EXIT, | 920 | .mismatch = XXXEXIT_TO_SOME_EXIT, |
921 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
900 | }, | 922 | }, |
901 | /* Do not reference cpuexit code/data from memexit code/data */ | 923 | /* Do not reference cpuexit code/data from memexit code/data */ |
902 | { | 924 | { |
903 | .fromsec = { MEM_EXIT_SECTIONS, NULL }, | 925 | .fromsec = { MEM_EXIT_SECTIONS, NULL }, |
904 | .tosec = { CPU_EXIT_SECTIONS, NULL }, | 926 | .tosec = { CPU_EXIT_SECTIONS, NULL }, |
905 | .mismatch = XXXEXIT_TO_EXIT, | 927 | .mismatch = XXXEXIT_TO_SOME_EXIT, |
928 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
906 | }, | 929 | }, |
907 | /* Do not reference memexit code/data from cpuexit code/data */ | 930 | /* Do not reference memexit code/data from cpuexit code/data */ |
908 | { | 931 | { |
909 | .fromsec = { CPU_EXIT_SECTIONS, NULL }, | 932 | .fromsec = { CPU_EXIT_SECTIONS, NULL }, |
910 | .tosec = { MEM_EXIT_SECTIONS, NULL }, | 933 | .tosec = { MEM_EXIT_SECTIONS, NULL }, |
911 | .mismatch = XXXEXIT_TO_EXIT, | 934 | .mismatch = XXXEXIT_TO_SOME_EXIT, |
935 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
912 | }, | 936 | }, |
913 | /* Do not use exit code/data from init code */ | 937 | /* Do not use exit code/data from init code */ |
914 | { | 938 | { |
915 | .fromsec = { ALL_INIT_SECTIONS, NULL }, | 939 | .fromsec = { ALL_INIT_SECTIONS, NULL }, |
916 | .tosec = { ALL_EXIT_SECTIONS, NULL }, | 940 | .tosec = { ALL_EXIT_SECTIONS, NULL }, |
917 | .mismatch = INIT_TO_EXIT, | 941 | .mismatch = ANY_INIT_TO_ANY_EXIT, |
942 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
918 | }, | 943 | }, |
919 | /* Do not use init code/data from exit code */ | 944 | /* Do not use init code/data from exit code */ |
920 | { | 945 | { |
921 | .fromsec = { ALL_EXIT_SECTIONS, NULL }, | 946 | .fromsec = { ALL_EXIT_SECTIONS, NULL }, |
922 | .tosec = { ALL_INIT_SECTIONS, NULL }, | 947 | .tosec = { ALL_INIT_SECTIONS, NULL }, |
923 | .mismatch = EXIT_TO_INIT, | 948 | .mismatch = ANY_EXIT_TO_ANY_INIT, |
949 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
924 | }, | 950 | }, |
925 | /* Do not export init/exit functions or data */ | 951 | /* Do not export init/exit functions or data */ |
926 | { | 952 | { |
927 | .fromsec = { "__ksymtab*", NULL }, | 953 | .fromsec = { "__ksymtab*", NULL }, |
928 | .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL }, | 954 | .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL }, |
929 | .mismatch = EXPORT_TO_INIT_EXIT | 955 | .mismatch = EXPORT_TO_INIT_EXIT, |
956 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
930 | } | 957 | } |
931 | }; | 958 | }; |
932 | 959 | ||
933 | static int section_mismatch(const char *fromsec, const char *tosec) | 960 | static const struct sectioncheck *section_mismatch( |
961 | const char *fromsec, const char *tosec) | ||
934 | { | 962 | { |
935 | int i; | 963 | int i; |
936 | int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck); | 964 | int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck); |
@@ -939,10 +967,10 @@ static int section_mismatch(const char *fromsec, const char *tosec) | |||
939 | for (i = 0; i < elems; i++) { | 967 | for (i = 0; i < elems; i++) { |
940 | if (match(fromsec, check->fromsec) && | 968 | if (match(fromsec, check->fromsec) && |
941 | match(tosec, check->tosec)) | 969 | match(tosec, check->tosec)) |
942 | return check->mismatch; | 970 | return check; |
943 | check++; | 971 | check++; |
944 | } | 972 | } |
945 | return NO_MISMATCH; | 973 | return NULL; |
946 | } | 974 | } |
947 | 975 | ||
948 | /** | 976 | /** |
@@ -961,7 +989,7 @@ static int section_mismatch(const char *fromsec, const char *tosec) | |||
961 | * Pattern 2: | 989 | * Pattern 2: |
962 | * Many drivers utilise a *driver container with references to | 990 | * Many drivers utilise a *driver container with references to |
963 | * add, remove, probe functions etc. | 991 | * add, remove, probe functions etc. |
964 | * These functions may often be marked __init and we do not want to | 992 | * These functions may often be marked __devinit and we do not want to |
965 | * warn here. | 993 | * warn here. |
966 | * the pattern is identified by: | 994 | * the pattern is identified by: |
967 | * tosec = init or exit section | 995 | * tosec = init or exit section |
@@ -982,7 +1010,8 @@ static int section_mismatch(const char *fromsec, const char *tosec) | |||
982 | * refsymname = __init_begin, _sinittext, _einittext | 1010 | * refsymname = __init_begin, _sinittext, _einittext |
983 | * | 1011 | * |
984 | **/ | 1012 | **/ |
985 | static int secref_whitelist(const char *fromsec, const char *fromsym, | 1013 | static int secref_whitelist(const struct sectioncheck *mismatch, |
1014 | const char *fromsec, const char *fromsym, | ||
986 | const char *tosec, const char *tosym) | 1015 | const char *tosec, const char *tosym) |
987 | { | 1016 | { |
988 | /* Check for pattern 1 */ | 1017 | /* Check for pattern 1 */ |
@@ -994,7 +1023,7 @@ static int secref_whitelist(const char *fromsec, const char *fromsym, | |||
994 | /* Check for pattern 2 */ | 1023 | /* Check for pattern 2 */ |
995 | if (match(tosec, init_exit_sections) && | 1024 | if (match(tosec, init_exit_sections) && |
996 | match(fromsec, data_sections) && | 1025 | match(fromsec, data_sections) && |
997 | match(fromsym, symbol_white_list)) | 1026 | match(fromsym, mismatch->symbol_white_list)) |
998 | return 0; | 1027 | return 0; |
999 | 1028 | ||
1000 | /* Check for pattern 3 */ | 1029 | /* Check for pattern 3 */ |
@@ -1155,7 +1184,8 @@ static int is_function(Elf_Sym *sym) | |||
1155 | * Try to find symbols near it so user can find it. | 1184 | * Try to find symbols near it so user can find it. |
1156 | * Check whitelist before warning - it may be a false positive. | 1185 | * Check whitelist before warning - it may be a false positive. |
1157 | */ | 1186 | */ |
1158 | static void report_sec_mismatch(const char *modname, enum mismatch mismatch, | 1187 | static void report_sec_mismatch(const char *modname, |
1188 | const struct sectioncheck *mismatch, | ||
1159 | const char *fromsec, | 1189 | const char *fromsec, |
1160 | unsigned long long fromaddr, | 1190 | unsigned long long fromaddr, |
1161 | const char *fromsym, | 1191 | const char *fromsym, |
@@ -1186,8 +1216,8 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch, | |||
1186 | modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec, | 1216 | modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec, |
1187 | tosym, to_p); | 1217 | tosym, to_p); |
1188 | 1218 | ||
1189 | switch (mismatch) { | 1219 | switch (mismatch->mismatch) { |
1190 | case TEXT_TO_INIT: | 1220 | case TEXT_TO_ANY_INIT: |
1191 | fprintf(stderr, | 1221 | fprintf(stderr, |
1192 | "The function %s%s() references\n" | 1222 | "The function %s%s() references\n" |
1193 | "the %s %s%s%s.\n" | 1223 | "the %s %s%s%s.\n" |
@@ -1197,8 +1227,8 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch, | |||
1197 | to, sec2annotation(tosec), tosym, to_p, | 1227 | to, sec2annotation(tosec), tosym, to_p, |
1198 | fromsym, sec2annotation(tosec), tosym); | 1228 | fromsym, sec2annotation(tosec), tosym); |
1199 | break; | 1229 | break; |
1200 | case DATA_TO_INIT: { | 1230 | case DATA_TO_ANY_INIT: { |
1201 | const char **s = symbol_white_list; | 1231 | const char *const *s = mismatch->symbol_white_list; |
1202 | fprintf(stderr, | 1232 | fprintf(stderr, |
1203 | "The variable %s references\n" | 1233 | "The variable %s references\n" |
1204 | "the %s %s%s%s\n" | 1234 | "the %s %s%s%s\n" |
@@ -1211,15 +1241,15 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch, | |||
1211 | fprintf(stderr, "\n"); | 1241 | fprintf(stderr, "\n"); |
1212 | break; | 1242 | break; |
1213 | } | 1243 | } |
1214 | case TEXT_TO_EXIT: | 1244 | case TEXT_TO_ANY_EXIT: |
1215 | fprintf(stderr, | 1245 | fprintf(stderr, |
1216 | "The function %s() references a %s in an exit section.\n" | 1246 | "The function %s() references a %s in an exit section.\n" |
1217 | "Often the %s %s%s has valid usage outside the exit section\n" | 1247 | "Often the %s %s%s has valid usage outside the exit section\n" |
1218 | "and the fix is to remove the %sannotation of %s.\n", | 1248 | "and the fix is to remove the %sannotation of %s.\n", |
1219 | fromsym, to, to, tosym, to_p, sec2annotation(tosec), tosym); | 1249 | fromsym, to, to, tosym, to_p, sec2annotation(tosec), tosym); |
1220 | break; | 1250 | break; |
1221 | case DATA_TO_EXIT: { | 1251 | case DATA_TO_ANY_EXIT: { |
1222 | const char **s = symbol_white_list; | 1252 | const char *const *s = mismatch->symbol_white_list; |
1223 | fprintf(stderr, | 1253 | fprintf(stderr, |
1224 | "The variable %s references\n" | 1254 | "The variable %s references\n" |
1225 | "the %s %s%s%s\n" | 1255 | "the %s %s%s%s\n" |
@@ -1232,8 +1262,8 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch, | |||
1232 | fprintf(stderr, "\n"); | 1262 | fprintf(stderr, "\n"); |
1233 | break; | 1263 | break; |
1234 | } | 1264 | } |
1235 | case XXXINIT_TO_INIT: | 1265 | case XXXINIT_TO_SOME_INIT: |
1236 | case XXXEXIT_TO_EXIT: | 1266 | case XXXEXIT_TO_SOME_EXIT: |
1237 | fprintf(stderr, | 1267 | fprintf(stderr, |
1238 | "The %s %s%s%s references\n" | 1268 | "The %s %s%s%s references\n" |
1239 | "a %s %s%s%s.\n" | 1269 | "a %s %s%s%s.\n" |
@@ -1243,7 +1273,7 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch, | |||
1243 | to, sec2annotation(tosec), tosym, to_p, | 1273 | to, sec2annotation(tosec), tosym, to_p, |
1244 | tosym, fromsym, tosym); | 1274 | tosym, fromsym, tosym); |
1245 | break; | 1275 | break; |
1246 | case INIT_TO_EXIT: | 1276 | case ANY_INIT_TO_ANY_EXIT: |
1247 | fprintf(stderr, | 1277 | fprintf(stderr, |
1248 | "The %s %s%s%s references\n" | 1278 | "The %s %s%s%s references\n" |
1249 | "a %s %s%s%s.\n" | 1279 | "a %s %s%s%s.\n" |
@@ -1256,7 +1286,7 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch, | |||
1256 | to, sec2annotation(tosec), tosym, to_p, | 1286 | to, sec2annotation(tosec), tosym, to_p, |
1257 | sec2annotation(tosec), tosym, to_p); | 1287 | sec2annotation(tosec), tosym, to_p); |
1258 | break; | 1288 | break; |
1259 | case EXIT_TO_INIT: | 1289 | case ANY_EXIT_TO_ANY_INIT: |
1260 | fprintf(stderr, | 1290 | fprintf(stderr, |
1261 | "The %s %s%s%s references\n" | 1291 | "The %s %s%s%s references\n" |
1262 | "a %s %s%s%s.\n" | 1292 | "a %s %s%s%s.\n" |
@@ -1275,8 +1305,6 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch, | |||
1275 | "Fix this by removing the %sannotation of %s " | 1305 | "Fix this by removing the %sannotation of %s " |
1276 | "or drop the export.\n", | 1306 | "or drop the export.\n", |
1277 | tosym, sec2annotation(tosec), sec2annotation(tosec), tosym); | 1307 | tosym, sec2annotation(tosec), sec2annotation(tosec), tosym); |
1278 | case NO_MISMATCH: | ||
1279 | /* To get warnings on missing members */ | ||
1280 | break; | 1308 | break; |
1281 | } | 1309 | } |
1282 | fprintf(stderr, "\n"); | 1310 | fprintf(stderr, "\n"); |
@@ -1286,11 +1314,11 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf, | |||
1286 | Elf_Rela *r, Elf_Sym *sym, const char *fromsec) | 1314 | Elf_Rela *r, Elf_Sym *sym, const char *fromsec) |
1287 | { | 1315 | { |
1288 | const char *tosec; | 1316 | const char *tosec; |
1289 | enum mismatch mismatch; | 1317 | const struct sectioncheck *mismatch; |
1290 | 1318 | ||
1291 | tosec = sec_name(elf, sym->st_shndx); | 1319 | tosec = sec_name(elf, sym->st_shndx); |
1292 | mismatch = section_mismatch(fromsec, tosec); | 1320 | mismatch = section_mismatch(fromsec, tosec); |
1293 | if (mismatch != NO_MISMATCH) { | 1321 | if (mismatch) { |
1294 | Elf_Sym *to; | 1322 | Elf_Sym *to; |
1295 | Elf_Sym *from; | 1323 | Elf_Sym *from; |
1296 | const char *tosym; | 1324 | const char *tosym; |
@@ -1302,7 +1330,8 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf, | |||
1302 | tosym = sym_name(elf, to); | 1330 | tosym = sym_name(elf, to); |
1303 | 1331 | ||
1304 | /* check whitelist - we may ignore it */ | 1332 | /* check whitelist - we may ignore it */ |
1305 | if (secref_whitelist(fromsec, fromsym, tosec, tosym)) { | 1333 | if (secref_whitelist(mismatch, |
1334 | fromsec, fromsym, tosec, tosym)) { | ||
1306 | report_sec_mismatch(modname, mismatch, | 1335 | report_sec_mismatch(modname, mismatch, |
1307 | fromsec, r->r_offset, fromsym, | 1336 | fromsec, r->r_offset, fromsym, |
1308 | is_function(from), tosec, tosym, | 1337 | is_function(from), tosec, tosym, |
@@ -1318,7 +1347,7 @@ static unsigned int *reloc_location(struct elf_info *elf, | |||
1318 | int section = sechdr->sh_info; | 1347 | int section = sechdr->sh_info; |
1319 | 1348 | ||
1320 | return (void *)elf->hdr + sechdrs[section].sh_offset + | 1349 | return (void *)elf->hdr + sechdrs[section].sh_offset + |
1321 | (r->r_offset - sechdrs[section].sh_addr); | 1350 | r->r_offset - sechdrs[section].sh_addr; |
1322 | } | 1351 | } |
1323 | 1352 | ||
1324 | static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) | 1353 | static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) |