aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2010-01-30 14:52:50 -0500
committerUwe Kleine-König <u.kleine-koenig@pengutronix.de>2010-01-30 14:52:50 -0500
commitaf92a82d0fec4dfd344b2ffd7a63e30f05c53938 (patch)
treeff65921f05b430ec98aac1bcc6323469a58feeca
parentfc2f7efadb755b020ad8fdf195515dacaf185e2d (diff)
modpost: make symbol white list a per mismatch type variable
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
-rw-r--r--scripts/mod/modpost.c49
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 */
820static 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
833static const char *head_sections[] = { ".head.text*", NULL }; 830static const char *head_sections[] = { ".head.text*", NULL };
834static const char *linker_symbols[] = 831static 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
855const struct sectioncheck sectioncheck[] = { 853const 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 **/
988static int secref_whitelist(const char *fromsec, const char *fromsym, 999static 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,