diff options
| author | Uwe Kleine-König <u.kleine-koenig@pengutronix.de> | 2010-01-30 14:52:50 -0500 |
|---|---|---|
| committer | Uwe Kleine-König <u.kleine-koenig@pengutronix.de> | 2010-01-30 14:52:50 -0500 |
| commit | af92a82d0fec4dfd344b2ffd7a63e30f05c53938 (patch) | |
| tree | ff65921f05b430ec98aac1bcc6323469a58feeca /scripts | |
| parent | fc2f7efadb755b020ad8fdf195515dacaf185e2d (diff) | |
modpost: make symbol white list a per mismatch type variable
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Diffstat (limited to 'scripts')
| -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, |
