diff options
Diffstat (limited to 'scripts/mod')
-rw-r--r-- | scripts/mod/modpost.c | 73 |
1 files changed, 57 insertions, 16 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 859bee4972e9..33122ca04e7c 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #define _GNU_SOURCE | 14 | #define _GNU_SOURCE |
15 | #include <stdio.h> | 15 | #include <stdio.h> |
16 | #include <ctype.h> | 16 | #include <ctype.h> |
17 | #include <string.h> | ||
17 | #include "modpost.h" | 18 | #include "modpost.h" |
18 | #include "../../include/generated/autoconf.h" | 19 | #include "../../include/generated/autoconf.h" |
19 | #include "../../include/linux/license.h" | 20 | #include "../../include/linux/license.h" |
@@ -789,6 +790,7 @@ static const char *section_white_list[] = | |||
789 | { | 790 | { |
790 | ".comment*", | 791 | ".comment*", |
791 | ".debug*", | 792 | ".debug*", |
793 | ".GCC-command-line", /* mn10300 */ | ||
792 | ".mdebug*", /* alpha, score, mips etc. */ | 794 | ".mdebug*", /* alpha, score, mips etc. */ |
793 | ".pdr", /* alpha, score, mips etc. */ | 795 | ".pdr", /* alpha, score, mips etc. */ |
794 | ".stab*", | 796 | ".stab*", |
@@ -1033,6 +1035,13 @@ static const struct sectioncheck *section_mismatch( | |||
1033 | * fromsec = .data* | 1035 | * fromsec = .data* |
1034 | * atsym =__param* | 1036 | * atsym =__param* |
1035 | * | 1037 | * |
1038 | * Pattern 1a: | ||
1039 | * module_param_call() ops can refer to __init set function if permissions=0 | ||
1040 | * The pattern is identified by: | ||
1041 | * tosec = .init.text | ||
1042 | * fromsec = .data* | ||
1043 | * atsym = __param_ops_* | ||
1044 | * | ||
1036 | * Pattern 2: | 1045 | * Pattern 2: |
1037 | * Many drivers utilise a *driver container with references to | 1046 | * Many drivers utilise a *driver container with references to |
1038 | * add, remove, probe functions etc. | 1047 | * add, remove, probe functions etc. |
@@ -1067,6 +1076,12 @@ static int secref_whitelist(const struct sectioncheck *mismatch, | |||
1067 | (strncmp(fromsym, "__param", strlen("__param")) == 0)) | 1076 | (strncmp(fromsym, "__param", strlen("__param")) == 0)) |
1068 | return 0; | 1077 | return 0; |
1069 | 1078 | ||
1079 | /* Check for pattern 1a */ | ||
1080 | if (strcmp(tosec, ".init.text") == 0 && | ||
1081 | match(fromsec, data_sections) && | ||
1082 | (strncmp(fromsym, "__param_ops_", strlen("__param_ops_")) == 0)) | ||
1083 | return 0; | ||
1084 | |||
1070 | /* Check for pattern 2 */ | 1085 | /* Check for pattern 2 */ |
1071 | if (match(tosec, init_exit_sections) && | 1086 | if (match(tosec, init_exit_sections) && |
1072 | match(fromsec, data_sections) && | 1087 | match(fromsec, data_sections) && |
@@ -1220,7 +1235,7 @@ static char *sec2annotation(const char *s) | |||
1220 | strcat(p, " "); | 1235 | strcat(p, " "); |
1221 | return r; | 1236 | return r; |
1222 | } else { | 1237 | } else { |
1223 | return ""; | 1238 | return strdup(""); |
1224 | } | 1239 | } |
1225 | } | 1240 | } |
1226 | 1241 | ||
@@ -1248,6 +1263,8 @@ static void report_sec_mismatch(const char *modname, | |||
1248 | { | 1263 | { |
1249 | const char *from, *from_p; | 1264 | const char *from, *from_p; |
1250 | const char *to, *to_p; | 1265 | const char *to, *to_p; |
1266 | char *prl_from; | ||
1267 | char *prl_to; | ||
1251 | 1268 | ||
1252 | switch (from_is_func) { | 1269 | switch (from_is_func) { |
1253 | case 0: from = "variable"; from_p = ""; break; | 1270 | case 0: from = "variable"; from_p = ""; break; |
@@ -1271,16 +1288,21 @@ static void report_sec_mismatch(const char *modname, | |||
1271 | 1288 | ||
1272 | switch (mismatch->mismatch) { | 1289 | switch (mismatch->mismatch) { |
1273 | case TEXT_TO_ANY_INIT: | 1290 | case TEXT_TO_ANY_INIT: |
1291 | prl_from = sec2annotation(fromsec); | ||
1292 | prl_to = sec2annotation(tosec); | ||
1274 | fprintf(stderr, | 1293 | fprintf(stderr, |
1275 | "The function %s%s() references\n" | 1294 | "The function %s%s() references\n" |
1276 | "the %s %s%s%s.\n" | 1295 | "the %s %s%s%s.\n" |
1277 | "This is often because %s lacks a %s\n" | 1296 | "This is often because %s lacks a %s\n" |
1278 | "annotation or the annotation of %s is wrong.\n", | 1297 | "annotation or the annotation of %s is wrong.\n", |
1279 | sec2annotation(fromsec), fromsym, | 1298 | prl_from, fromsym, |
1280 | to, sec2annotation(tosec), tosym, to_p, | 1299 | to, prl_to, tosym, to_p, |
1281 | fromsym, sec2annotation(tosec), tosym); | 1300 | fromsym, prl_to, tosym); |
1301 | free(prl_from); | ||
1302 | free(prl_to); | ||
1282 | break; | 1303 | break; |
1283 | case DATA_TO_ANY_INIT: { | 1304 | case DATA_TO_ANY_INIT: { |
1305 | prl_to = sec2annotation(tosec); | ||
1284 | const char *const *s = mismatch->symbol_white_list; | 1306 | const char *const *s = mismatch->symbol_white_list; |
1285 | fprintf(stderr, | 1307 | fprintf(stderr, |
1286 | "The variable %s references\n" | 1308 | "The variable %s references\n" |
@@ -1288,20 +1310,24 @@ static void report_sec_mismatch(const char *modname, | |||
1288 | "If the reference is valid then annotate the\n" | 1310 | "If the reference is valid then annotate the\n" |
1289 | "variable with __init* or __refdata (see linux/init.h) " | 1311 | "variable with __init* or __refdata (see linux/init.h) " |
1290 | "or name the variable:\n", | 1312 | "or name the variable:\n", |
1291 | fromsym, to, sec2annotation(tosec), tosym, to_p); | 1313 | fromsym, to, prl_to, tosym, to_p); |
1292 | while (*s) | 1314 | while (*s) |
1293 | fprintf(stderr, "%s, ", *s++); | 1315 | fprintf(stderr, "%s, ", *s++); |
1294 | fprintf(stderr, "\n"); | 1316 | fprintf(stderr, "\n"); |
1317 | free(prl_to); | ||
1295 | break; | 1318 | break; |
1296 | } | 1319 | } |
1297 | case TEXT_TO_ANY_EXIT: | 1320 | case TEXT_TO_ANY_EXIT: |
1321 | prl_to = sec2annotation(tosec); | ||
1298 | fprintf(stderr, | 1322 | fprintf(stderr, |
1299 | "The function %s() references a %s in an exit section.\n" | 1323 | "The function %s() references a %s in an exit section.\n" |
1300 | "Often the %s %s%s has valid usage outside the exit section\n" | 1324 | "Often the %s %s%s has valid usage outside the exit section\n" |
1301 | "and the fix is to remove the %sannotation of %s.\n", | 1325 | "and the fix is to remove the %sannotation of %s.\n", |
1302 | fromsym, to, to, tosym, to_p, sec2annotation(tosec), tosym); | 1326 | fromsym, to, to, tosym, to_p, prl_to, tosym); |
1327 | free(prl_to); | ||
1303 | break; | 1328 | break; |
1304 | case DATA_TO_ANY_EXIT: { | 1329 | case DATA_TO_ANY_EXIT: { |
1330 | prl_to = sec2annotation(tosec); | ||
1305 | const char *const *s = mismatch->symbol_white_list; | 1331 | const char *const *s = mismatch->symbol_white_list; |
1306 | fprintf(stderr, | 1332 | fprintf(stderr, |
1307 | "The variable %s references\n" | 1333 | "The variable %s references\n" |
@@ -1309,24 +1335,31 @@ static void report_sec_mismatch(const char *modname, | |||
1309 | "If the reference is valid then annotate the\n" | 1335 | "If the reference is valid then annotate the\n" |
1310 | "variable with __exit* (see linux/init.h) or " | 1336 | "variable with __exit* (see linux/init.h) or " |
1311 | "name the variable:\n", | 1337 | "name the variable:\n", |
1312 | fromsym, to, sec2annotation(tosec), tosym, to_p); | 1338 | fromsym, to, prl_to, tosym, to_p); |
1313 | while (*s) | 1339 | while (*s) |
1314 | fprintf(stderr, "%s, ", *s++); | 1340 | fprintf(stderr, "%s, ", *s++); |
1315 | fprintf(stderr, "\n"); | 1341 | fprintf(stderr, "\n"); |
1342 | free(prl_to); | ||
1316 | break; | 1343 | break; |
1317 | } | 1344 | } |
1318 | case XXXINIT_TO_SOME_INIT: | 1345 | case XXXINIT_TO_SOME_INIT: |
1319 | case XXXEXIT_TO_SOME_EXIT: | 1346 | case XXXEXIT_TO_SOME_EXIT: |
1347 | prl_from = sec2annotation(fromsec); | ||
1348 | prl_to = sec2annotation(tosec); | ||
1320 | fprintf(stderr, | 1349 | fprintf(stderr, |
1321 | "The %s %s%s%s references\n" | 1350 | "The %s %s%s%s references\n" |
1322 | "a %s %s%s%s.\n" | 1351 | "a %s %s%s%s.\n" |
1323 | "If %s is only used by %s then\n" | 1352 | "If %s is only used by %s then\n" |
1324 | "annotate %s with a matching annotation.\n", | 1353 | "annotate %s with a matching annotation.\n", |
1325 | from, sec2annotation(fromsec), fromsym, from_p, | 1354 | from, prl_from, fromsym, from_p, |
1326 | to, sec2annotation(tosec), tosym, to_p, | 1355 | to, prl_to, tosym, to_p, |
1327 | tosym, fromsym, tosym); | 1356 | tosym, fromsym, tosym); |
1357 | free(prl_from); | ||
1358 | free(prl_to); | ||
1328 | break; | 1359 | break; |
1329 | case ANY_INIT_TO_ANY_EXIT: | 1360 | case ANY_INIT_TO_ANY_EXIT: |
1361 | prl_from = sec2annotation(fromsec); | ||
1362 | prl_to = sec2annotation(tosec); | ||
1330 | fprintf(stderr, | 1363 | fprintf(stderr, |
1331 | "The %s %s%s%s references\n" | 1364 | "The %s %s%s%s references\n" |
1332 | "a %s %s%s%s.\n" | 1365 | "a %s %s%s%s.\n" |
@@ -1335,11 +1368,15 @@ static void report_sec_mismatch(const char *modname, | |||
1335 | "uses functionality in the exit path.\n" | 1368 | "uses functionality in the exit path.\n" |
1336 | "The fix is often to remove the %sannotation of\n" | 1369 | "The fix is often to remove the %sannotation of\n" |
1337 | "%s%s so it may be used outside an exit section.\n", | 1370 | "%s%s so it may be used outside an exit section.\n", |
1338 | from, sec2annotation(fromsec), fromsym, from_p, | 1371 | from, prl_from, fromsym, from_p, |
1339 | to, sec2annotation(tosec), tosym, to_p, | 1372 | to, prl_to, tosym, to_p, |
1340 | sec2annotation(tosec), tosym, to_p); | 1373 | prl_to, tosym, to_p); |
1374 | free(prl_from); | ||
1375 | free(prl_to); | ||
1341 | break; | 1376 | break; |
1342 | case ANY_EXIT_TO_ANY_INIT: | 1377 | case ANY_EXIT_TO_ANY_INIT: |
1378 | prl_from = sec2annotation(fromsec); | ||
1379 | prl_to = sec2annotation(tosec); | ||
1343 | fprintf(stderr, | 1380 | fprintf(stderr, |
1344 | "The %s %s%s%s references\n" | 1381 | "The %s %s%s%s references\n" |
1345 | "a %s %s%s%s.\n" | 1382 | "a %s %s%s%s.\n" |
@@ -1348,16 +1385,20 @@ static void report_sec_mismatch(const char *modname, | |||
1348 | "uses functionality in the init path.\n" | 1385 | "uses functionality in the init path.\n" |
1349 | "The fix is often to remove the %sannotation of\n" | 1386 | "The fix is often to remove the %sannotation of\n" |
1350 | "%s%s so it may be used outside an init section.\n", | 1387 | "%s%s so it may be used outside an init section.\n", |
1351 | from, sec2annotation(fromsec), fromsym, from_p, | 1388 | from, prl_from, fromsym, from_p, |
1352 | to, sec2annotation(tosec), tosym, to_p, | 1389 | to, prl_to, tosym, to_p, |
1353 | sec2annotation(tosec), tosym, to_p); | 1390 | prl_to, tosym, to_p); |
1391 | free(prl_from); | ||
1392 | free(prl_to); | ||
1354 | break; | 1393 | break; |
1355 | case EXPORT_TO_INIT_EXIT: | 1394 | case EXPORT_TO_INIT_EXIT: |
1395 | prl_to = sec2annotation(tosec); | ||
1356 | fprintf(stderr, | 1396 | fprintf(stderr, |
1357 | "The symbol %s is exported and annotated %s\n" | 1397 | "The symbol %s is exported and annotated %s\n" |
1358 | "Fix this by removing the %sannotation of %s " | 1398 | "Fix this by removing the %sannotation of %s " |
1359 | "or drop the export.\n", | 1399 | "or drop the export.\n", |
1360 | tosym, sec2annotation(tosec), sec2annotation(tosec), tosym); | 1400 | tosym, prl_to, prl_to, tosym); |
1401 | free(prl_to); | ||
1361 | break; | 1402 | break; |
1362 | } | 1403 | } |
1363 | fprintf(stderr, "\n"); | 1404 | fprintf(stderr, "\n"); |