aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/mod/modpost.c
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/mod/modpost.c')
-rw-r--r--scripts/mod/modpost.c341
1 files changed, 287 insertions, 54 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index d439856f8176..91ee1b2e0f9a 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -776,6 +776,7 @@ static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr)
776 * "foo" will match an exact string equal to "foo" 776 * "foo" will match an exact string equal to "foo"
777 * "*foo" will match a string that ends with "foo" 777 * "*foo" will match a string that ends with "foo"
778 * "foo*" will match a string that begins with "foo" 778 * "foo*" will match a string that begins with "foo"
779 * "*foo*" will match a string that contains "foo"
779 */ 780 */
780static int match(const char *sym, const char * const pat[]) 781static int match(const char *sym, const char * const pat[])
781{ 782{
@@ -784,8 +785,17 @@ static int match(const char *sym, const char * const pat[])
784 p = *pat++; 785 p = *pat++;
785 const char *endp = p + strlen(p) - 1; 786 const char *endp = p + strlen(p) - 1;
786 787
788 /* "*foo*" */
789 if (*p == '*' && *endp == '*') {
790 char *here, *bare = strndup(p + 1, strlen(p) - 2);
791
792 here = strstr(sym, bare);
793 free(bare);
794 if (here != NULL)
795 return 1;
796 }
787 /* "*foo" */ 797 /* "*foo" */
788 if (*p == '*') { 798 else if (*p == '*') {
789 if (strrcmp(sym, p + 1) == 0) 799 if (strrcmp(sym, p + 1) == 0)
790 return 1; 800 return 1;
791 } 801 }
@@ -873,7 +883,10 @@ static void check_section(const char *modname, struct elf_info *elf,
873#define ALL_EXIT_SECTIONS EXIT_SECTIONS, ALL_XXXEXIT_SECTIONS 883#define ALL_EXIT_SECTIONS EXIT_SECTIONS, ALL_XXXEXIT_SECTIONS
874 884
875#define DATA_SECTIONS ".data", ".data.rel" 885#define DATA_SECTIONS ".data", ".data.rel"
876#define TEXT_SECTIONS ".text", ".text.unlikely" 886#define TEXT_SECTIONS ".text", ".text.unlikely", ".sched.text", \
887 ".kprobes.text"
888#define OTHER_TEXT_SECTIONS ".ref.text", ".head.text", ".spinlock.text", \
889 ".fixup", ".entry.text", ".exception.text", ".text.*"
877 890
878#define INIT_SECTIONS ".init.*" 891#define INIT_SECTIONS ".init.*"
879#define MEM_INIT_SECTIONS ".meminit.*" 892#define MEM_INIT_SECTIONS ".meminit.*"
@@ -881,6 +894,9 @@ static void check_section(const char *modname, struct elf_info *elf,
881#define EXIT_SECTIONS ".exit.*" 894#define EXIT_SECTIONS ".exit.*"
882#define MEM_EXIT_SECTIONS ".memexit.*" 895#define MEM_EXIT_SECTIONS ".memexit.*"
883 896
897#define ALL_TEXT_SECTIONS ALL_INIT_TEXT_SECTIONS, ALL_EXIT_TEXT_SECTIONS, \
898 TEXT_SECTIONS, OTHER_TEXT_SECTIONS
899
884/* init data sections */ 900/* init data sections */
885static const char *const init_data_sections[] = 901static const char *const init_data_sections[] =
886 { ALL_INIT_DATA_SECTIONS, NULL }; 902 { ALL_INIT_DATA_SECTIONS, NULL };
@@ -892,6 +908,9 @@ static const char *const init_sections[] = { ALL_INIT_SECTIONS, NULL };
892static const char *const init_exit_sections[] = 908static const char *const init_exit_sections[] =
893 {ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL }; 909 {ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL };
894 910
911/* all text sections */
912static const char *const text_sections[] = { ALL_TEXT_SECTIONS, NULL };
913
895/* data section */ 914/* data section */
896static const char *const data_sections[] = { DATA_SECTIONS, NULL }; 915static const char *const data_sections[] = { DATA_SECTIONS, NULL };
897 916
@@ -910,6 +929,7 @@ static const char *const data_sections[] = { DATA_SECTIONS, NULL };
910static const char *const head_sections[] = { ".head.text*", NULL }; 929static const char *const head_sections[] = { ".head.text*", NULL };
911static const char *const linker_symbols[] = 930static const char *const linker_symbols[] =
912 { "__init_begin", "_sinittext", "_einittext", NULL }; 931 { "__init_begin", "_sinittext", "_einittext", NULL };
932static const char *const optim_symbols[] = { "*.constprop.*", NULL };
913 933
914enum mismatch { 934enum mismatch {
915 TEXT_TO_ANY_INIT, 935 TEXT_TO_ANY_INIT,
@@ -921,34 +941,65 @@ enum mismatch {
921 ANY_INIT_TO_ANY_EXIT, 941 ANY_INIT_TO_ANY_EXIT,
922 ANY_EXIT_TO_ANY_INIT, 942 ANY_EXIT_TO_ANY_INIT,
923 EXPORT_TO_INIT_EXIT, 943 EXPORT_TO_INIT_EXIT,
944 EXTABLE_TO_NON_TEXT,
924}; 945};
925 946
947/**
948 * Describe how to match sections on different criterias:
949 *
950 * @fromsec: Array of sections to be matched.
951 *
952 * @bad_tosec: Relocations applied to a section in @fromsec to a section in
953 * this array is forbidden (black-list). Can be empty.
954 *
955 * @good_tosec: Relocations applied to a section in @fromsec must be
956 * targetting sections in this array (white-list). Can be empty.
957 *
958 * @mismatch: Type of mismatch.
959 *
960 * @symbol_white_list: Do not match a relocation to a symbol in this list
961 * even if it is targetting a section in @bad_to_sec.
962 *
963 * @handler: Specific handler to call when a match is found. If NULL,
964 * default_mismatch_handler() will be called.
965 *
966 */
926struct sectioncheck { 967struct sectioncheck {
927 const char *fromsec[20]; 968 const char *fromsec[20];
928 const char *tosec[20]; 969 const char *bad_tosec[20];
970 const char *good_tosec[20];
929 enum mismatch mismatch; 971 enum mismatch mismatch;
930 const char *symbol_white_list[20]; 972 const char *symbol_white_list[20];
973 void (*handler)(const char *modname, struct elf_info *elf,
974 const struct sectioncheck* const mismatch,
975 Elf_Rela *r, Elf_Sym *sym, const char *fromsec);
976
931}; 977};
932 978
979static void extable_mismatch_handler(const char *modname, struct elf_info *elf,
980 const struct sectioncheck* const mismatch,
981 Elf_Rela *r, Elf_Sym *sym,
982 const char *fromsec);
983
933static const struct sectioncheck sectioncheck[] = { 984static const struct sectioncheck sectioncheck[] = {
934/* Do not reference init/exit code/data from 985/* Do not reference init/exit code/data from
935 * normal code and data 986 * normal code and data
936 */ 987 */
937{ 988{
938 .fromsec = { TEXT_SECTIONS, NULL }, 989 .fromsec = { TEXT_SECTIONS, NULL },
939 .tosec = { ALL_INIT_SECTIONS, NULL }, 990 .bad_tosec = { ALL_INIT_SECTIONS, NULL },
940 .mismatch = TEXT_TO_ANY_INIT, 991 .mismatch = TEXT_TO_ANY_INIT,
941 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, 992 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
942}, 993},
943{ 994{
944 .fromsec = { DATA_SECTIONS, NULL }, 995 .fromsec = { DATA_SECTIONS, NULL },
945 .tosec = { ALL_XXXINIT_SECTIONS, NULL }, 996 .bad_tosec = { ALL_XXXINIT_SECTIONS, NULL },
946 .mismatch = DATA_TO_ANY_INIT, 997 .mismatch = DATA_TO_ANY_INIT,
947 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, 998 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
948}, 999},
949{ 1000{
950 .fromsec = { DATA_SECTIONS, NULL }, 1001 .fromsec = { DATA_SECTIONS, NULL },
951 .tosec = { INIT_SECTIONS, NULL }, 1002 .bad_tosec = { INIT_SECTIONS, NULL },
952 .mismatch = DATA_TO_ANY_INIT, 1003 .mismatch = DATA_TO_ANY_INIT,
953 .symbol_white_list = { 1004 .symbol_white_list = {
954 "*_template", "*_timer", "*_sht", "*_ops", 1005 "*_template", "*_timer", "*_sht", "*_ops",
@@ -957,56 +1008,66 @@ static const struct sectioncheck sectioncheck[] = {
957}, 1008},
958{ 1009{
959 .fromsec = { TEXT_SECTIONS, NULL }, 1010 .fromsec = { TEXT_SECTIONS, NULL },
960 .tosec = { ALL_EXIT_SECTIONS, NULL }, 1011 .bad_tosec = { ALL_EXIT_SECTIONS, NULL },
961 .mismatch = TEXT_TO_ANY_EXIT, 1012 .mismatch = TEXT_TO_ANY_EXIT,
962 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, 1013 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
963}, 1014},
964{ 1015{
965 .fromsec = { DATA_SECTIONS, NULL }, 1016 .fromsec = { DATA_SECTIONS, NULL },
966 .tosec = { ALL_EXIT_SECTIONS, NULL }, 1017 .bad_tosec = { ALL_EXIT_SECTIONS, NULL },
967 .mismatch = DATA_TO_ANY_EXIT, 1018 .mismatch = DATA_TO_ANY_EXIT,
968 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, 1019 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
969}, 1020},
970/* Do not reference init code/data from meminit code/data */ 1021/* Do not reference init code/data from meminit code/data */
971{ 1022{
972 .fromsec = { ALL_XXXINIT_SECTIONS, NULL }, 1023 .fromsec = { ALL_XXXINIT_SECTIONS, NULL },
973 .tosec = { INIT_SECTIONS, NULL }, 1024 .bad_tosec = { INIT_SECTIONS, NULL },
974 .mismatch = XXXINIT_TO_SOME_INIT, 1025 .mismatch = XXXINIT_TO_SOME_INIT,
975 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, 1026 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
976}, 1027},
977/* Do not reference exit code/data from memexit code/data */ 1028/* Do not reference exit code/data from memexit code/data */
978{ 1029{
979 .fromsec = { ALL_XXXEXIT_SECTIONS, NULL }, 1030 .fromsec = { ALL_XXXEXIT_SECTIONS, NULL },
980 .tosec = { EXIT_SECTIONS, NULL }, 1031 .bad_tosec = { EXIT_SECTIONS, NULL },
981 .mismatch = XXXEXIT_TO_SOME_EXIT, 1032 .mismatch = XXXEXIT_TO_SOME_EXIT,
982 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, 1033 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
983}, 1034},
984/* Do not use exit code/data from init code */ 1035/* Do not use exit code/data from init code */
985{ 1036{
986 .fromsec = { ALL_INIT_SECTIONS, NULL }, 1037 .fromsec = { ALL_INIT_SECTIONS, NULL },
987 .tosec = { ALL_EXIT_SECTIONS, NULL }, 1038 .bad_tosec = { ALL_EXIT_SECTIONS, NULL },
988 .mismatch = ANY_INIT_TO_ANY_EXIT, 1039 .mismatch = ANY_INIT_TO_ANY_EXIT,
989 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, 1040 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
990}, 1041},
991/* Do not use init code/data from exit code */ 1042/* Do not use init code/data from exit code */
992{ 1043{
993 .fromsec = { ALL_EXIT_SECTIONS, NULL }, 1044 .fromsec = { ALL_EXIT_SECTIONS, NULL },
994 .tosec = { ALL_INIT_SECTIONS, NULL }, 1045 .bad_tosec = { ALL_INIT_SECTIONS, NULL },
995 .mismatch = ANY_EXIT_TO_ANY_INIT, 1046 .mismatch = ANY_EXIT_TO_ANY_INIT,
996 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, 1047 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
997}, 1048},
998{ 1049{
999 .fromsec = { ALL_PCI_INIT_SECTIONS, NULL }, 1050 .fromsec = { ALL_PCI_INIT_SECTIONS, NULL },
1000 .tosec = { INIT_SECTIONS, NULL }, 1051 .bad_tosec = { INIT_SECTIONS, NULL },
1001 .mismatch = ANY_INIT_TO_ANY_EXIT, 1052 .mismatch = ANY_INIT_TO_ANY_EXIT,
1002 .symbol_white_list = { NULL }, 1053 .symbol_white_list = { NULL },
1003}, 1054},
1004/* Do not export init/exit functions or data */ 1055/* Do not export init/exit functions or data */
1005{ 1056{
1006 .fromsec = { "__ksymtab*", NULL }, 1057 .fromsec = { "__ksymtab*", NULL },
1007 .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL }, 1058 .bad_tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
1008 .mismatch = EXPORT_TO_INIT_EXIT, 1059 .mismatch = EXPORT_TO_INIT_EXIT,
1009 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, 1060 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
1061},
1062{
1063 .fromsec = { "__ex_table", NULL },
1064 /* If you're adding any new black-listed sections in here, consider
1065 * adding a special 'printer' for them in scripts/check_extable.
1066 */
1067 .bad_tosec = { ".altinstr_replacement", NULL },
1068 .good_tosec = {ALL_TEXT_SECTIONS , NULL},
1069 .mismatch = EXTABLE_TO_NON_TEXT,
1070 .handler = extable_mismatch_handler,
1010} 1071}
1011}; 1072};
1012 1073
@@ -1017,10 +1078,22 @@ static const struct sectioncheck *section_mismatch(
1017 int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck); 1078 int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck);
1018 const struct sectioncheck *check = &sectioncheck[0]; 1079 const struct sectioncheck *check = &sectioncheck[0];
1019 1080
1081 /*
1082 * The target section could be the SHT_NUL section when we're
1083 * handling relocations to un-resolved symbols, trying to match it
1084 * doesn't make much sense and causes build failures on parisc and
1085 * mn10300 architectures.
1086 */
1087 if (*tosec == '\0')
1088 return NULL;
1089
1020 for (i = 0; i < elems; i++) { 1090 for (i = 0; i < elems; i++) {
1021 if (match(fromsec, check->fromsec) && 1091 if (match(fromsec, check->fromsec)) {
1022 match(tosec, check->tosec)) 1092 if (check->bad_tosec[0] && match(tosec, check->bad_tosec))
1023 return check; 1093 return check;
1094 if (check->good_tosec[0] && !match(tosec, check->good_tosec))
1095 return check;
1096 }
1024 check++; 1097 check++;
1025 } 1098 }
1026 return NULL; 1099 return NULL;
@@ -1067,6 +1140,17 @@ static const struct sectioncheck *section_mismatch(
1067 * This pattern is identified by 1140 * This pattern is identified by
1068 * refsymname = __init_begin, _sinittext, _einittext 1141 * refsymname = __init_begin, _sinittext, _einittext
1069 * 1142 *
1143 * Pattern 5:
1144 * GCC may optimize static inlines when fed constant arg(s) resulting
1145 * in functions like cpumask_empty() -- generating an associated symbol
1146 * cpumask_empty.constprop.3 that appears in the audit. If the const that
1147 * is passed in comes from __init, like say nmi_ipi_mask, we get a
1148 * meaningless section warning. May need to add isra symbols too...
1149 * This pattern is identified by
1150 * tosec = init section
1151 * fromsec = text section
1152 * refsymname = *.constprop.*
1153 *
1070 **/ 1154 **/
1071static int secref_whitelist(const struct sectioncheck *mismatch, 1155static int secref_whitelist(const struct sectioncheck *mismatch,
1072 const char *fromsec, const char *fromsym, 1156 const char *fromsec, const char *fromsym,
@@ -1099,6 +1183,12 @@ static int secref_whitelist(const struct sectioncheck *mismatch,
1099 if (match(tosym, linker_symbols)) 1183 if (match(tosym, linker_symbols))
1100 return 0; 1184 return 0;
1101 1185
1186 /* Check for pattern 5 */
1187 if (match(fromsec, text_sections) &&
1188 match(tosec, init_sections) &&
1189 match(fromsym, optim_symbols))
1190 return 0;
1191
1102 return 1; 1192 return 1;
1103} 1193}
1104 1194
@@ -1261,6 +1351,15 @@ static void print_section_list(const char * const list[20])
1261 fprintf(stderr, "\n"); 1351 fprintf(stderr, "\n");
1262} 1352}
1263 1353
1354static inline void get_pretty_name(int is_func, const char** name, const char** name_p)
1355{
1356 switch (is_func) {
1357 case 0: *name = "variable"; *name_p = ""; break;
1358 case 1: *name = "function"; *name_p = "()"; break;
1359 default: *name = "(unknown reference)"; *name_p = ""; break;
1360 }
1361}
1362
1264/* 1363/*
1265 * Print a warning about a section mismatch. 1364 * Print a warning about a section mismatch.
1266 * Try to find symbols near it so user can find it. 1365 * Try to find symbols near it so user can find it.
@@ -1280,21 +1379,13 @@ static void report_sec_mismatch(const char *modname,
1280 char *prl_from; 1379 char *prl_from;
1281 char *prl_to; 1380 char *prl_to;
1282 1381
1283 switch (from_is_func) {
1284 case 0: from = "variable"; from_p = ""; break;
1285 case 1: from = "function"; from_p = "()"; break;
1286 default: from = "(unknown reference)"; from_p = ""; break;
1287 }
1288 switch (to_is_func) {
1289 case 0: to = "variable"; to_p = ""; break;
1290 case 1: to = "function"; to_p = "()"; break;
1291 default: to = "(unknown reference)"; to_p = ""; break;
1292 }
1293
1294 sec_mismatch_count++; 1382 sec_mismatch_count++;
1295 if (!sec_mismatch_verbose) 1383 if (!sec_mismatch_verbose)
1296 return; 1384 return;
1297 1385
1386 get_pretty_name(from_is_func, &from, &from_p);
1387 get_pretty_name(to_is_func, &to, &to_p);
1388
1298 warn("%s(%s+0x%llx): Section mismatch in reference from the %s %s%s " 1389 warn("%s(%s+0x%llx): Section mismatch in reference from the %s %s%s "
1299 "to the %s %s:%s%s\n", 1390 "to the %s %s:%s%s\n",
1300 modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec, 1391 modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec,
@@ -1408,41 +1499,179 @@ static void report_sec_mismatch(const char *modname,
1408 tosym, prl_to, prl_to, tosym); 1499 tosym, prl_to, prl_to, tosym);
1409 free(prl_to); 1500 free(prl_to);
1410 break; 1501 break;
1502 case EXTABLE_TO_NON_TEXT:
1503 fatal("There's a special handler for this mismatch type, "
1504 "we should never get here.");
1505 break;
1411 } 1506 }
1412 fprintf(stderr, "\n"); 1507 fprintf(stderr, "\n");
1413} 1508}
1414 1509
1415static void check_section_mismatch(const char *modname, struct elf_info *elf, 1510static void default_mismatch_handler(const char *modname, struct elf_info *elf,
1416 Elf_Rela *r, Elf_Sym *sym, const char *fromsec) 1511 const struct sectioncheck* const mismatch,
1512 Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
1417{ 1513{
1418 const char *tosec; 1514 const char *tosec;
1419 const struct sectioncheck *mismatch; 1515 Elf_Sym *to;
1516 Elf_Sym *from;
1517 const char *tosym;
1518 const char *fromsym;
1519
1520 from = find_elf_symbol2(elf, r->r_offset, fromsec);
1521 fromsym = sym_name(elf, from);
1522
1523 if (!strncmp(fromsym, "reference___initcall",
1524 sizeof("reference___initcall")-1))
1525 return;
1420 1526
1421 tosec = sec_name(elf, get_secindex(elf, sym)); 1527 tosec = sec_name(elf, get_secindex(elf, sym));
1422 mismatch = section_mismatch(fromsec, tosec); 1528 to = find_elf_symbol(elf, r->r_addend, sym);
1529 tosym = sym_name(elf, to);
1530
1531 /* check whitelist - we may ignore it */
1532 if (secref_whitelist(mismatch,
1533 fromsec, fromsym, tosec, tosym)) {
1534 report_sec_mismatch(modname, mismatch,
1535 fromsec, r->r_offset, fromsym,
1536 is_function(from), tosec, tosym,
1537 is_function(to));
1538 }
1539}
1540
1541static int is_executable_section(struct elf_info* elf, unsigned int section_index)
1542{
1543 if (section_index > elf->num_sections)
1544 fatal("section_index is outside elf->num_sections!\n");
1545
1546 return ((elf->sechdrs[section_index].sh_flags & SHF_EXECINSTR) == SHF_EXECINSTR);
1547}
1548
1549/*
1550 * We rely on a gross hack in section_rel[a]() calling find_extable_entry_size()
1551 * to know the sizeof(struct exception_table_entry) for the target architecture.
1552 */
1553static unsigned int extable_entry_size = 0;
1554static void find_extable_entry_size(const char* const sec, const Elf_Rela* r)
1555{
1556 /*
1557 * If we're currently checking the second relocation within __ex_table,
1558 * that relocation offset tells us the offsetof(struct
1559 * exception_table_entry, fixup) which is equal to sizeof(struct
1560 * exception_table_entry) divided by two. We use that to our advantage
1561 * since there's no portable way to get that size as every architecture
1562 * seems to go with different sized types. Not pretty but better than
1563 * hard-coding the size for every architecture..
1564 */
1565 if (!extable_entry_size)
1566 extable_entry_size = r->r_offset * 2;
1567}
1568
1569static inline bool is_extable_fault_address(Elf_Rela *r)
1570{
1571 /*
1572 * extable_entry_size is only discovered after we've handled the
1573 * _second_ relocation in __ex_table, so only abort when we're not
1574 * handling the first reloc and extable_entry_size is zero.
1575 */
1576 if (r->r_offset && extable_entry_size == 0)
1577 fatal("extable_entry size hasn't been discovered!\n");
1578
1579 return ((r->r_offset == 0) ||
1580 (r->r_offset % extable_entry_size == 0));
1581}
1582
1583#define is_second_extable_reloc(Start, Cur, Sec) \
1584 (((Cur) == (Start) + 1) && (strcmp("__ex_table", (Sec)) == 0))
1585
1586static void report_extable_warnings(const char* modname, struct elf_info* elf,
1587 const struct sectioncheck* const mismatch,
1588 Elf_Rela* r, Elf_Sym* sym,
1589 const char* fromsec, const char* tosec)
1590{
1591 Elf_Sym* fromsym = find_elf_symbol2(elf, r->r_offset, fromsec);
1592 const char* fromsym_name = sym_name(elf, fromsym);
1593 Elf_Sym* tosym = find_elf_symbol(elf, r->r_addend, sym);
1594 const char* tosym_name = sym_name(elf, tosym);
1595 const char* from_pretty_name;
1596 const char* from_pretty_name_p;
1597 const char* to_pretty_name;
1598 const char* to_pretty_name_p;
1599
1600 get_pretty_name(is_function(fromsym),
1601 &from_pretty_name, &from_pretty_name_p);
1602 get_pretty_name(is_function(tosym),
1603 &to_pretty_name, &to_pretty_name_p);
1604
1605 warn("%s(%s+0x%lx): Section mismatch in reference"
1606 " from the %s %s%s to the %s %s:%s%s\n",
1607 modname, fromsec, (long)r->r_offset, from_pretty_name,
1608 fromsym_name, from_pretty_name_p,
1609 to_pretty_name, tosec, tosym_name, to_pretty_name_p);
1610
1611 if (!match(tosec, mismatch->bad_tosec) &&
1612 is_executable_section(elf, get_secindex(elf, sym)))
1613 fprintf(stderr,
1614 "The relocation at %s+0x%lx references\n"
1615 "section \"%s\" which is not in the list of\n"
1616 "authorized sections. If you're adding a new section\n"
1617 "and/or if this reference is valid, add \"%s\" to the\n"
1618 "list of authorized sections to jump to on fault.\n"
1619 "This can be achieved by adding \"%s\" to \n"
1620 "OTHER_TEXT_SECTIONS in scripts/mod/modpost.c.\n",
1621 fromsec, (long)r->r_offset, tosec, tosec, tosec);
1622}
1623
1624static void extable_mismatch_handler(const char* modname, struct elf_info *elf,
1625 const struct sectioncheck* const mismatch,
1626 Elf_Rela* r, Elf_Sym* sym,
1627 const char *fromsec)
1628{
1629 const char* tosec = sec_name(elf, get_secindex(elf, sym));
1630
1631 sec_mismatch_count++;
1632
1633 if (sec_mismatch_verbose)
1634 report_extable_warnings(modname, elf, mismatch, r, sym,
1635 fromsec, tosec);
1636
1637 if (match(tosec, mismatch->bad_tosec))
1638 fatal("The relocation at %s+0x%lx references\n"
1639 "section \"%s\" which is black-listed.\n"
1640 "Something is seriously wrong and should be fixed.\n"
1641 "You might get more information about where this is\n"
1642 "coming from by using scripts/check_extable.sh %s\n",
1643 fromsec, (long)r->r_offset, tosec, modname);
1644 else if (!is_executable_section(elf, get_secindex(elf, sym))) {
1645 if (is_extable_fault_address(r))
1646 fatal("The relocation at %s+0x%lx references\n"
1647 "section \"%s\" which is not executable, IOW\n"
1648 "it is not possible for the kernel to fault\n"
1649 "at that address. Something is seriously wrong\n"
1650 "and should be fixed.\n",
1651 fromsec, (long)r->r_offset, tosec);
1652 else
1653 fatal("The relocation at %s+0x%lx references\n"
1654 "section \"%s\" which is not executable, IOW\n"
1655 "the kernel will fault if it ever tries to\n"
1656 "jump to it. Something is seriously wrong\n"
1657 "and should be fixed.\n",
1658 fromsec, (long)r->r_offset, tosec);
1659 }
1660}
1661
1662static void check_section_mismatch(const char *modname, struct elf_info *elf,
1663 Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
1664{
1665 const char *tosec = sec_name(elf, get_secindex(elf, sym));;
1666 const struct sectioncheck *mismatch = section_mismatch(fromsec, tosec);
1667
1423 if (mismatch) { 1668 if (mismatch) {
1424 Elf_Sym *to; 1669 if (mismatch->handler)
1425 Elf_Sym *from; 1670 mismatch->handler(modname, elf, mismatch,
1426 const char *tosym; 1671 r, sym, fromsec);
1427 const char *fromsym; 1672 else
1428 1673 default_mismatch_handler(modname, elf, mismatch,
1429 from = find_elf_symbol2(elf, r->r_offset, fromsec); 1674 r, sym, fromsec);
1430 fromsym = sym_name(elf, from);
1431 to = find_elf_symbol(elf, r->r_addend, sym);
1432 tosym = sym_name(elf, to);
1433
1434 if (!strncmp(fromsym, "reference___initcall",
1435 sizeof("reference___initcall")-1))
1436 return;
1437
1438 /* check whitelist - we may ignore it */
1439 if (secref_whitelist(mismatch,
1440 fromsec, fromsym, tosec, tosym)) {
1441 report_sec_mismatch(modname, mismatch,
1442 fromsec, r->r_offset, fromsym,
1443 is_function(from), tosec, tosym,
1444 is_function(to));
1445 }
1446 } 1675 }
1447} 1676}
1448 1677
@@ -1582,6 +1811,8 @@ static void section_rela(const char *modname, struct elf_info *elf,
1582 /* Skip special sections */ 1811 /* Skip special sections */
1583 if (is_shndx_special(sym->st_shndx)) 1812 if (is_shndx_special(sym->st_shndx))
1584 continue; 1813 continue;
1814 if (is_second_extable_reloc(start, rela, fromsec))
1815 find_extable_entry_size(fromsec, &r);
1585 check_section_mismatch(modname, elf, &r, sym, fromsec); 1816 check_section_mismatch(modname, elf, &r, sym, fromsec);
1586 } 1817 }
1587} 1818}
@@ -1640,6 +1871,8 @@ static void section_rel(const char *modname, struct elf_info *elf,
1640 /* Skip special sections */ 1871 /* Skip special sections */
1641 if (is_shndx_special(sym->st_shndx)) 1872 if (is_shndx_special(sym->st_shndx))
1642 continue; 1873 continue;
1874 if (is_second_extable_reloc(start, rel, fromsec))
1875 find_extable_entry_size(fromsec, &r);
1643 check_section_mismatch(modname, elf, &r, sym, fromsec); 1876 check_section_mismatch(modname, elf, &r, sym, fromsec);
1644 } 1877 }
1645} 1878}