aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/mod
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/mod')
-rw-r--r--scripts/mod/modpost.c73
1 files changed, 57 insertions, 16 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index c827309c29cf..1ec7158b6c1f 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) &&
@@ -1217,7 +1232,7 @@ static char *sec2annotation(const char *s)
1217 strcat(p, " "); 1232 strcat(p, " ");
1218 return r; /* we leak her but we do not care */ 1233 return r; /* we leak her but we do not care */
1219 } else { 1234 } else {
1220 return ""; 1235 return strdup("");
1221 } 1236 }
1222} 1237}
1223 1238
@@ -1245,6 +1260,8 @@ static void report_sec_mismatch(const char *modname,
1245{ 1260{
1246 const char *from, *from_p; 1261 const char *from, *from_p;
1247 const char *to, *to_p; 1262 const char *to, *to_p;
1263 char *prl_from;
1264 char *prl_to;
1248 1265
1249 switch (from_is_func) { 1266 switch (from_is_func) {
1250 case 0: from = "variable"; from_p = ""; break; 1267 case 0: from = "variable"; from_p = ""; break;
@@ -1268,16 +1285,21 @@ static void report_sec_mismatch(const char *modname,
1268 1285
1269 switch (mismatch->mismatch) { 1286 switch (mismatch->mismatch) {
1270 case TEXT_TO_ANY_INIT: 1287 case TEXT_TO_ANY_INIT:
1288 prl_from = sec2annotation(fromsec);
1289 prl_to = sec2annotation(tosec);
1271 fprintf(stderr, 1290 fprintf(stderr,
1272 "The function %s%s() references\n" 1291 "The function %s%s() references\n"
1273 "the %s %s%s%s.\n" 1292 "the %s %s%s%s.\n"
1274 "This is often because %s lacks a %s\n" 1293 "This is often because %s lacks a %s\n"
1275 "annotation or the annotation of %s is wrong.\n", 1294 "annotation or the annotation of %s is wrong.\n",
1276 sec2annotation(fromsec), fromsym, 1295 prl_from, fromsym,
1277 to, sec2annotation(tosec), tosym, to_p, 1296 to, prl_to, tosym, to_p,
1278 fromsym, sec2annotation(tosec), tosym); 1297 fromsym, prl_to, tosym);
1298 free(prl_from);
1299 free(prl_to);
1279 break; 1300 break;
1280 case DATA_TO_ANY_INIT: { 1301 case DATA_TO_ANY_INIT: {
1302 prl_to = sec2annotation(tosec);
1281 const char *const *s = mismatch->symbol_white_list; 1303 const char *const *s = mismatch->symbol_white_list;
1282 fprintf(stderr, 1304 fprintf(stderr,
1283 "The variable %s references\n" 1305 "The variable %s references\n"
@@ -1285,20 +1307,24 @@ static void report_sec_mismatch(const char *modname,
1285 "If the reference is valid then annotate the\n" 1307 "If the reference is valid then annotate the\n"
1286 "variable with __init* or __refdata (see linux/init.h) " 1308 "variable with __init* or __refdata (see linux/init.h) "
1287 "or name the variable:\n", 1309 "or name the variable:\n",
1288 fromsym, to, sec2annotation(tosec), tosym, to_p); 1310 fromsym, to, prl_to, tosym, to_p);
1289 while (*s) 1311 while (*s)
1290 fprintf(stderr, "%s, ", *s++); 1312 fprintf(stderr, "%s, ", *s++);
1291 fprintf(stderr, "\n"); 1313 fprintf(stderr, "\n");
1314 free(prl_to);
1292 break; 1315 break;
1293 } 1316 }
1294 case TEXT_TO_ANY_EXIT: 1317 case TEXT_TO_ANY_EXIT:
1318 prl_to = sec2annotation(tosec);
1295 fprintf(stderr, 1319 fprintf(stderr,
1296 "The function %s() references a %s in an exit section.\n" 1320 "The function %s() references a %s in an exit section.\n"
1297 "Often the %s %s%s has valid usage outside the exit section\n" 1321 "Often the %s %s%s has valid usage outside the exit section\n"
1298 "and the fix is to remove the %sannotation of %s.\n", 1322 "and the fix is to remove the %sannotation of %s.\n",
1299 fromsym, to, to, tosym, to_p, sec2annotation(tosec), tosym); 1323 fromsym, to, to, tosym, to_p, prl_to, tosym);
1324 free(prl_to);
1300 break; 1325 break;
1301 case DATA_TO_ANY_EXIT: { 1326 case DATA_TO_ANY_EXIT: {
1327 prl_to = sec2annotation(tosec);
1302 const char *const *s = mismatch->symbol_white_list; 1328 const char *const *s = mismatch->symbol_white_list;
1303 fprintf(stderr, 1329 fprintf(stderr,
1304 "The variable %s references\n" 1330 "The variable %s references\n"
@@ -1306,24 +1332,31 @@ static void report_sec_mismatch(const char *modname,
1306 "If the reference is valid then annotate the\n" 1332 "If the reference is valid then annotate the\n"
1307 "variable with __exit* (see linux/init.h) or " 1333 "variable with __exit* (see linux/init.h) or "
1308 "name the variable:\n", 1334 "name the variable:\n",
1309 fromsym, to, sec2annotation(tosec), tosym, to_p); 1335 fromsym, to, prl_to, tosym, to_p);
1310 while (*s) 1336 while (*s)
1311 fprintf(stderr, "%s, ", *s++); 1337 fprintf(stderr, "%s, ", *s++);
1312 fprintf(stderr, "\n"); 1338 fprintf(stderr, "\n");
1339 free(prl_to);
1313 break; 1340 break;
1314 } 1341 }
1315 case XXXINIT_TO_SOME_INIT: 1342 case XXXINIT_TO_SOME_INIT:
1316 case XXXEXIT_TO_SOME_EXIT: 1343 case XXXEXIT_TO_SOME_EXIT:
1344 prl_from = sec2annotation(fromsec);
1345 prl_to = sec2annotation(tosec);
1317 fprintf(stderr, 1346 fprintf(stderr,
1318 "The %s %s%s%s references\n" 1347 "The %s %s%s%s references\n"
1319 "a %s %s%s%s.\n" 1348 "a %s %s%s%s.\n"
1320 "If %s is only used by %s then\n" 1349 "If %s is only used by %s then\n"
1321 "annotate %s with a matching annotation.\n", 1350 "annotate %s with a matching annotation.\n",
1322 from, sec2annotation(fromsec), fromsym, from_p, 1351 from, prl_from, fromsym, from_p,
1323 to, sec2annotation(tosec), tosym, to_p, 1352 to, prl_to, tosym, to_p,
1324 tosym, fromsym, tosym); 1353 tosym, fromsym, tosym);
1354 free(prl_from);
1355 free(prl_to);
1325 break; 1356 break;
1326 case ANY_INIT_TO_ANY_EXIT: 1357 case ANY_INIT_TO_ANY_EXIT:
1358 prl_from = sec2annotation(fromsec);
1359 prl_to = sec2annotation(tosec);
1327 fprintf(stderr, 1360 fprintf(stderr,
1328 "The %s %s%s%s references\n" 1361 "The %s %s%s%s references\n"
1329 "a %s %s%s%s.\n" 1362 "a %s %s%s%s.\n"
@@ -1332,11 +1365,15 @@ static void report_sec_mismatch(const char *modname,
1332 "uses functionality in the exit path.\n" 1365 "uses functionality in the exit path.\n"
1333 "The fix is often to remove the %sannotation of\n" 1366 "The fix is often to remove the %sannotation of\n"
1334 "%s%s so it may be used outside an exit section.\n", 1367 "%s%s so it may be used outside an exit section.\n",
1335 from, sec2annotation(fromsec), fromsym, from_p, 1368 from, prl_from, fromsym, from_p,
1336 to, sec2annotation(tosec), tosym, to_p, 1369 to, prl_to, tosym, to_p,
1337 sec2annotation(tosec), tosym, to_p); 1370 prl_to, tosym, to_p);
1371 free(prl_from);
1372 free(prl_to);
1338 break; 1373 break;
1339 case ANY_EXIT_TO_ANY_INIT: 1374 case ANY_EXIT_TO_ANY_INIT:
1375 prl_from = sec2annotation(fromsec);
1376 prl_to = sec2annotation(tosec);
1340 fprintf(stderr, 1377 fprintf(stderr,
1341 "The %s %s%s%s references\n" 1378 "The %s %s%s%s references\n"
1342 "a %s %s%s%s.\n" 1379 "a %s %s%s%s.\n"
@@ -1345,16 +1382,20 @@ static void report_sec_mismatch(const char *modname,
1345 "uses functionality in the init path.\n" 1382 "uses functionality in the init path.\n"
1346 "The fix is often to remove the %sannotation of\n" 1383 "The fix is often to remove the %sannotation of\n"
1347 "%s%s so it may be used outside an init section.\n", 1384 "%s%s so it may be used outside an init section.\n",
1348 from, sec2annotation(fromsec), fromsym, from_p, 1385 from, prl_from, fromsym, from_p,
1349 to, sec2annotation(tosec), tosym, to_p, 1386 to, prl_to, tosym, to_p,
1350 sec2annotation(tosec), tosym, to_p); 1387 prl_to, tosym, to_p);
1388 free(prl_from);
1389 free(prl_to);
1351 break; 1390 break;
1352 case EXPORT_TO_INIT_EXIT: 1391 case EXPORT_TO_INIT_EXIT:
1392 prl_to = sec2annotation(tosec);
1353 fprintf(stderr, 1393 fprintf(stderr,
1354 "The symbol %s is exported and annotated %s\n" 1394 "The symbol %s is exported and annotated %s\n"
1355 "Fix this by removing the %sannotation of %s " 1395 "Fix this by removing the %sannotation of %s "
1356 "or drop the export.\n", 1396 "or drop the export.\n",
1357 tosym, sec2annotation(tosec), sec2annotation(tosec), tosym); 1397 tosym, prl_to, prl_to, tosym);
1398 free(prl_to);
1358 break; 1399 break;
1359 } 1400 }
1360 fprintf(stderr, "\n"); 1401 fprintf(stderr, "\n");