diff options
-rw-r--r-- | scripts/mod/modpost.c | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index a94bd10ad2de..5dbe4db2bd42 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
@@ -817,18 +817,15 @@ static const char *data_sections[] = { DATA_SECTIONS, NULL }; | |||
817 | 817 | ||
818 | 818 | ||
819 | /* symbols in .data that may refer to init/exit sections */ | 819 | /* symbols in .data that may refer to init/exit sections */ |
820 | static const char *symbol_white_list[] = | 820 | #define DEFAULT_SYMBOL_WHITE_LIST \ |
821 | { | 821 | "*driver", \ |
822 | "*driver", | 822 | "*_template", /* scsi uses *_template a lot */ \ |
823 | "*_template", /* scsi uses *_template a lot */ | 823 | "*_timer", /* arm uses ops structures named _timer a lot */ \ |
824 | "*_timer", /* arm uses ops structures named _timer a lot */ | 824 | "*_sht", /* scsi also used *_sht to some extent */ \ |
825 | "*_sht", /* scsi also used *_sht to some extent */ | 825 | "*_ops", \ |
826 | "*_ops", | 826 | "*_probe", \ |
827 | "*_probe", | 827 | "*_probe_one", \ |
828 | "*_probe_one", | 828 | "*_console" |
829 | "*_console", | ||
830 | NULL | ||
831 | }; | ||
832 | 829 | ||
833 | static const char *head_sections[] = { ".head.text*", NULL }; | 830 | static const char *head_sections[] = { ".head.text*", NULL }; |
834 | static const char *linker_symbols[] = | 831 | static const char *linker_symbols[] = |
@@ -850,6 +847,7 @@ struct sectioncheck { | |||
850 | const char *fromsec[20]; | 847 | const char *fromsec[20]; |
851 | const char *tosec[20]; | 848 | const char *tosec[20]; |
852 | enum mismatch mismatch; | 849 | enum mismatch mismatch; |
850 | const char *symbol_white_list[20]; | ||
853 | }; | 851 | }; |
854 | 852 | ||
855 | const struct sectioncheck sectioncheck[] = { | 853 | const struct sectioncheck sectioncheck[] = { |
@@ -860,75 +858,88 @@ const struct sectioncheck sectioncheck[] = { | |||
860 | .fromsec = { TEXT_SECTIONS, NULL }, | 858 | .fromsec = { TEXT_SECTIONS, NULL }, |
861 | .tosec = { ALL_INIT_SECTIONS, NULL }, | 859 | .tosec = { ALL_INIT_SECTIONS, NULL }, |
862 | .mismatch = TEXT_TO_ANY_INIT, | 860 | .mismatch = TEXT_TO_ANY_INIT, |
861 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
863 | }, | 862 | }, |
864 | { | 863 | { |
865 | .fromsec = { DATA_SECTIONS, NULL }, | 864 | .fromsec = { DATA_SECTIONS, NULL }, |
866 | .tosec = { ALL_INIT_SECTIONS, NULL }, | 865 | .tosec = { ALL_INIT_SECTIONS, NULL }, |
867 | .mismatch = DATA_TO_ANY_INIT, | 866 | .mismatch = DATA_TO_ANY_INIT, |
867 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
868 | }, | 868 | }, |
869 | { | 869 | { |
870 | .fromsec = { TEXT_SECTIONS, NULL }, | 870 | .fromsec = { TEXT_SECTIONS, NULL }, |
871 | .tosec = { ALL_EXIT_SECTIONS, NULL }, | 871 | .tosec = { ALL_EXIT_SECTIONS, NULL }, |
872 | .mismatch = TEXT_TO_ANY_EXIT, | 872 | .mismatch = TEXT_TO_ANY_EXIT, |
873 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
873 | }, | 874 | }, |
874 | { | 875 | { |
875 | .fromsec = { DATA_SECTIONS, NULL }, | 876 | .fromsec = { DATA_SECTIONS, NULL }, |
876 | .tosec = { ALL_EXIT_SECTIONS, NULL }, | 877 | .tosec = { ALL_EXIT_SECTIONS, NULL }, |
877 | .mismatch = DATA_TO_ANY_EXIT, | 878 | .mismatch = DATA_TO_ANY_EXIT, |
879 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
878 | }, | 880 | }, |
879 | /* Do not reference init code/data from devinit/cpuinit/meminit code/data */ | 881 | /* Do not reference init code/data from devinit/cpuinit/meminit code/data */ |
880 | { | 882 | { |
881 | .fromsec = { ALL_XXXINIT_SECTIONS, NULL }, | 883 | .fromsec = { ALL_XXXINIT_SECTIONS, NULL }, |
882 | .tosec = { INIT_SECTIONS, NULL }, | 884 | .tosec = { INIT_SECTIONS, NULL }, |
883 | .mismatch = XXXINIT_TO_SOME_INIT, | 885 | .mismatch = XXXINIT_TO_SOME_INIT, |
886 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
884 | }, | 887 | }, |
885 | /* Do not reference cpuinit code/data from meminit code/data */ | 888 | /* Do not reference cpuinit code/data from meminit code/data */ |
886 | { | 889 | { |
887 | .fromsec = { MEM_INIT_SECTIONS, NULL }, | 890 | .fromsec = { MEM_INIT_SECTIONS, NULL }, |
888 | .tosec = { CPU_INIT_SECTIONS, NULL }, | 891 | .tosec = { CPU_INIT_SECTIONS, NULL }, |
889 | .mismatch = XXXINIT_TO_SOME_INIT, | 892 | .mismatch = XXXINIT_TO_SOME_INIT, |
893 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
890 | }, | 894 | }, |
891 | /* Do not reference meminit code/data from cpuinit code/data */ | 895 | /* Do not reference meminit code/data from cpuinit code/data */ |
892 | { | 896 | { |
893 | .fromsec = { CPU_INIT_SECTIONS, NULL }, | 897 | .fromsec = { CPU_INIT_SECTIONS, NULL }, |
894 | .tosec = { MEM_INIT_SECTIONS, NULL }, | 898 | .tosec = { MEM_INIT_SECTIONS, NULL }, |
895 | .mismatch = XXXINIT_TO_SOME_INIT, | 899 | .mismatch = XXXINIT_TO_SOME_INIT, |
900 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
896 | }, | 901 | }, |
897 | /* Do not reference exit code/data from devexit/cpuexit/memexit code/data */ | 902 | /* Do not reference exit code/data from devexit/cpuexit/memexit code/data */ |
898 | { | 903 | { |
899 | .fromsec = { ALL_XXXEXIT_SECTIONS, NULL }, | 904 | .fromsec = { ALL_XXXEXIT_SECTIONS, NULL }, |
900 | .tosec = { EXIT_SECTIONS, NULL }, | 905 | .tosec = { EXIT_SECTIONS, NULL }, |
901 | .mismatch = XXXEXIT_TO_SOME_EXIT, | 906 | .mismatch = XXXEXIT_TO_SOME_EXIT, |
907 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
902 | }, | 908 | }, |
903 | /* Do not reference cpuexit code/data from memexit code/data */ | 909 | /* Do not reference cpuexit code/data from memexit code/data */ |
904 | { | 910 | { |
905 | .fromsec = { MEM_EXIT_SECTIONS, NULL }, | 911 | .fromsec = { MEM_EXIT_SECTIONS, NULL }, |
906 | .tosec = { CPU_EXIT_SECTIONS, NULL }, | 912 | .tosec = { CPU_EXIT_SECTIONS, NULL }, |
907 | .mismatch = XXXEXIT_TO_SOME_EXIT, | 913 | .mismatch = XXXEXIT_TO_SOME_EXIT, |
914 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
908 | }, | 915 | }, |
909 | /* Do not reference memexit code/data from cpuexit code/data */ | 916 | /* Do not reference memexit code/data from cpuexit code/data */ |
910 | { | 917 | { |
911 | .fromsec = { CPU_EXIT_SECTIONS, NULL }, | 918 | .fromsec = { CPU_EXIT_SECTIONS, NULL }, |
912 | .tosec = { MEM_EXIT_SECTIONS, NULL }, | 919 | .tosec = { MEM_EXIT_SECTIONS, NULL }, |
913 | .mismatch = XXXEXIT_TO_SOME_EXIT, | 920 | .mismatch = XXXEXIT_TO_SOME_EXIT, |
921 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
914 | }, | 922 | }, |
915 | /* Do not use exit code/data from init code */ | 923 | /* Do not use exit code/data from init code */ |
916 | { | 924 | { |
917 | .fromsec = { ALL_INIT_SECTIONS, NULL }, | 925 | .fromsec = { ALL_INIT_SECTIONS, NULL }, |
918 | .tosec = { ALL_EXIT_SECTIONS, NULL }, | 926 | .tosec = { ALL_EXIT_SECTIONS, NULL }, |
919 | .mismatch = ANY_INIT_TO_ANY_EXIT, | 927 | .mismatch = ANY_INIT_TO_ANY_EXIT, |
928 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
920 | }, | 929 | }, |
921 | /* Do not use init code/data from exit code */ | 930 | /* Do not use init code/data from exit code */ |
922 | { | 931 | { |
923 | .fromsec = { ALL_EXIT_SECTIONS, NULL }, | 932 | .fromsec = { ALL_EXIT_SECTIONS, NULL }, |
924 | .tosec = { ALL_INIT_SECTIONS, NULL }, | 933 | .tosec = { ALL_INIT_SECTIONS, NULL }, |
925 | .mismatch = ANY_EXIT_TO_ANY_INIT, | 934 | .mismatch = ANY_EXIT_TO_ANY_INIT, |
935 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
926 | }, | 936 | }, |
927 | /* Do not export init/exit functions or data */ | 937 | /* Do not export init/exit functions or data */ |
928 | { | 938 | { |
929 | .fromsec = { "__ksymtab*", NULL }, | 939 | .fromsec = { "__ksymtab*", NULL }, |
930 | .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL }, | 940 | .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL }, |
931 | .mismatch = EXPORT_TO_INIT_EXIT | 941 | .mismatch = EXPORT_TO_INIT_EXIT, |
942 | .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, | ||
932 | } | 943 | } |
933 | }; | 944 | }; |
934 | 945 | ||
@@ -985,7 +996,8 @@ static const struct sectioncheck *section_mismatch( | |||
985 | * refsymname = __init_begin, _sinittext, _einittext | 996 | * refsymname = __init_begin, _sinittext, _einittext |
986 | * | 997 | * |
987 | **/ | 998 | **/ |
988 | static int secref_whitelist(const char *fromsec, const char *fromsym, | 999 | static int secref_whitelist(const struct sectioncheck *mismatch, |
1000 | const char *fromsec, const char *fromsym, | ||
989 | const char *tosec, const char *tosym) | 1001 | const char *tosec, const char *tosym) |
990 | { | 1002 | { |
991 | /* Check for pattern 1 */ | 1003 | /* Check for pattern 1 */ |
@@ -997,7 +1009,7 @@ static int secref_whitelist(const char *fromsec, const char *fromsym, | |||
997 | /* Check for pattern 2 */ | 1009 | /* Check for pattern 2 */ |
998 | if (match(tosec, init_exit_sections) && | 1010 | if (match(tosec, init_exit_sections) && |
999 | match(fromsec, data_sections) && | 1011 | match(fromsec, data_sections) && |
1000 | match(fromsym, symbol_white_list)) | 1012 | match(fromsym, mismatch->symbol_white_list)) |
1001 | return 0; | 1013 | return 0; |
1002 | 1014 | ||
1003 | /* Check for pattern 3 */ | 1015 | /* Check for pattern 3 */ |
@@ -1202,7 +1214,7 @@ static void report_sec_mismatch(const char *modname, | |||
1202 | fromsym, sec2annotation(tosec), tosym); | 1214 | fromsym, sec2annotation(tosec), tosym); |
1203 | break; | 1215 | break; |
1204 | case DATA_TO_ANY_INIT: { | 1216 | case DATA_TO_ANY_INIT: { |
1205 | const char **s = symbol_white_list; | 1217 | const char *const *s = mismatch->symbol_white_list; |
1206 | fprintf(stderr, | 1218 | fprintf(stderr, |
1207 | "The variable %s references\n" | 1219 | "The variable %s references\n" |
1208 | "the %s %s%s%s\n" | 1220 | "the %s %s%s%s\n" |
@@ -1223,7 +1235,7 @@ static void report_sec_mismatch(const char *modname, | |||
1223 | fromsym, to, to, tosym, to_p, sec2annotation(tosec), tosym); | 1235 | fromsym, to, to, tosym, to_p, sec2annotation(tosec), tosym); |
1224 | break; | 1236 | break; |
1225 | case DATA_TO_ANY_EXIT: { | 1237 | case DATA_TO_ANY_EXIT: { |
1226 | const char **s = symbol_white_list; | 1238 | const char *const *s = mismatch->symbol_white_list; |
1227 | fprintf(stderr, | 1239 | fprintf(stderr, |
1228 | "The variable %s references\n" | 1240 | "The variable %s references\n" |
1229 | "the %s %s%s%s\n" | 1241 | "the %s %s%s%s\n" |
@@ -1304,7 +1316,8 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf, | |||
1304 | tosym = sym_name(elf, to); | 1316 | tosym = sym_name(elf, to); |
1305 | 1317 | ||
1306 | /* check whitelist - we may ignore it */ | 1318 | /* check whitelist - we may ignore it */ |
1307 | if (secref_whitelist(fromsec, fromsym, tosec, tosym)) { | 1319 | if (secref_whitelist(mismatch, |
1320 | fromsec, fromsym, tosec, tosym)) { | ||
1308 | report_sec_mismatch(modname, mismatch, | 1321 | report_sec_mismatch(modname, mismatch, |
1309 | fromsec, r->r_offset, fromsym, | 1322 | fromsec, r->r_offset, fromsym, |
1310 | is_function(from), tosec, tosym, | 1323 | is_function(from), tosec, tosym, |