diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/mod/modpost.c | 305 |
1 files changed, 128 insertions, 177 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index e4630135979c..6c206b9212b1 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
@@ -605,6 +605,61 @@ static int strrcmp(const char *s, const char *sub) | |||
605 | return memcmp(s + slen - sublen, sub, sublen); | 605 | return memcmp(s + slen - sublen, sub, sublen); |
606 | } | 606 | } |
607 | 607 | ||
608 | /* if sym is empty or point to a string | ||
609 | * like ".[0-9]+" then return 1. | ||
610 | * This is the optional prefix added by ld to some sections | ||
611 | */ | ||
612 | static int number_prefix(const char *sym) | ||
613 | { | ||
614 | if (*sym++ == '\0') | ||
615 | return 1; | ||
616 | if (*sym != '.') | ||
617 | return 0; | ||
618 | do { | ||
619 | char c = *sym++; | ||
620 | if (c < '0' || c > '9') | ||
621 | return 0; | ||
622 | } while (*sym); | ||
623 | return 1; | ||
624 | } | ||
625 | |||
626 | /* The pattern is an array of simple patterns. | ||
627 | * "foo" will match an exact string equal to "foo" | ||
628 | * "foo*" will match a string that begins with "foo" | ||
629 | * "foo$" will match a string equal to "foo" or "foo.1" | ||
630 | * where the '1' can be any number including several digits. | ||
631 | * The $ syntax is for sections where ld append a dot number | ||
632 | * to make section name unique. | ||
633 | */ | ||
634 | int match(const char *sym, const char * const pat[]) | ||
635 | { | ||
636 | const char *p; | ||
637 | while (*pat) { | ||
638 | p = *pat++; | ||
639 | const char *endp = p + strlen(p) - 1; | ||
640 | |||
641 | /* "foo*" */ | ||
642 | if (*endp == '*') { | ||
643 | if (strncmp(sym, p, strlen(p) - 1) == 0) | ||
644 | return 1; | ||
645 | } | ||
646 | /* "foo$" */ | ||
647 | else if (*endp == '$') { | ||
648 | if (strncmp(sym, p, strlen(p) - 1) == 0) { | ||
649 | if (number_prefix(sym + strlen(p) - 1)) | ||
650 | return 1; | ||
651 | } | ||
652 | } | ||
653 | /* no wildcards */ | ||
654 | else { | ||
655 | if (strcmp(p, sym) == 0) | ||
656 | return 1; | ||
657 | } | ||
658 | } | ||
659 | /* no match */ | ||
660 | return 0; | ||
661 | } | ||
662 | |||
608 | /* | 663 | /* |
609 | * Functions used only during module init is marked __init and is stored in | 664 | * Functions used only during module init is marked __init and is stored in |
610 | * a .init.text section. Likewise data is marked __initdata and stored in | 665 | * a .init.text section. Likewise data is marked __initdata and stored in |
@@ -653,6 +708,68 @@ static int data_section(const char *name) | |||
653 | return 0; | 708 | return 0; |
654 | } | 709 | } |
655 | 710 | ||
711 | /* sections that we do not want to do full section mismatch check on */ | ||
712 | static const char *section_white_list[] = | ||
713 | { ".debug*", ".stab*", ".note*", ".got*", ".toc*", NULL }; | ||
714 | |||
715 | #define INIT_DATA_SECTIONS ".init.data$" | ||
716 | #define EXIT_DATA_SECTIONS ".exit.data$" | ||
717 | |||
718 | #define INIT_TEXT_SECTIONS ".init.text$" | ||
719 | #define EXIT_TEXT_SECTIONS ".exit.text$" | ||
720 | |||
721 | #define INIT_SECTIONS INIT_DATA_SECTIONS, INIT_TEXT_SECTIONS | ||
722 | #define EXIT_SECTIONS EXIT_DATA_SECTIONS, EXIT_TEXT_SECTIONS | ||
723 | |||
724 | #define DATA_SECTIONS ".data$" | ||
725 | #define TEXT_SECTIONS ".text$" | ||
726 | |||
727 | struct sectioncheck { | ||
728 | const char *fromsec[20]; | ||
729 | const char *tosec[20]; | ||
730 | }; | ||
731 | |||
732 | const struct sectioncheck sectioncheck[] = { | ||
733 | /* Do not reference init/exit code/data from | ||
734 | * normal code and data | ||
735 | */ | ||
736 | { | ||
737 | .fromsec = { TEXT_SECTIONS, DATA_SECTIONS, NULL }, | ||
738 | .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL } | ||
739 | }, | ||
740 | /* Do not use exit code/data from init code */ | ||
741 | { | ||
742 | .fromsec = { INIT_SECTIONS, NULL }, | ||
743 | .tosec = { EXIT_SECTIONS, NULL }, | ||
744 | }, | ||
745 | /* Do not use init code/data from exit code */ | ||
746 | { | ||
747 | .fromsec = { EXIT_SECTIONS, NULL }, | ||
748 | .tosec = { INIT_SECTIONS, NULL } | ||
749 | }, | ||
750 | /* Do not export init/exit functions or data */ | ||
751 | { | ||
752 | .fromsec = { "__ksymtab*", NULL }, | ||
753 | .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL } | ||
754 | } | ||
755 | }; | ||
756 | |||
757 | static int section_mismatch(const char *fromsec, const char *tosec) | ||
758 | { | ||
759 | int i; | ||
760 | int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck); | ||
761 | const struct sectioncheck *check = §ioncheck[0]; | ||
762 | |||
763 | for (i = 0; i < elems; i++) { | ||
764 | if (match(fromsec, check->fromsec) && | ||
765 | match(tosec, check->tosec)) | ||
766 | return 1; | ||
767 | check++; | ||
768 | } | ||
769 | return 0; | ||
770 | } | ||
771 | |||
772 | |||
656 | /** | 773 | /** |
657 | * Whitelist to allow certain references to pass with no warning. | 774 | * Whitelist to allow certain references to pass with no warning. |
658 | * | 775 | * |
@@ -695,18 +812,11 @@ static int data_section(const char *name) | |||
695 | * This pattern is identified by | 812 | * This pattern is identified by |
696 | * refsymname = __init_begin, _sinittext, _einittext | 813 | * refsymname = __init_begin, _sinittext, _einittext |
697 | * | 814 | * |
698 | * Pattern 5: | ||
699 | * Xtensa uses literal sections for constants that are accessed PC-relative. | ||
700 | * Literal sections may safely reference their text sections. | ||
701 | * (Note that the name for the literal section omits any trailing '.text') | ||
702 | * tosec = <section>[.text] | ||
703 | * fromsec = <section>.literal | ||
704 | **/ | 815 | **/ |
705 | static int secref_whitelist(const char *modname, const char *tosec, | 816 | static int secref_whitelist(const char *modname, const char *tosec, |
706 | const char *fromsec, const char *atsym, | 817 | const char *fromsec, const char *atsym, |
707 | const char *refsymname) | 818 | const char *refsymname) |
708 | { | 819 | { |
709 | int len; | ||
710 | const char **s; | 820 | const char **s; |
711 | const char *pat2sym[] = { | 821 | const char *pat2sym[] = { |
712 | "driver", | 822 | "driver", |
@@ -757,15 +867,6 @@ static int secref_whitelist(const char *modname, const char *tosec, | |||
757 | if (strcmp(refsymname, *s) == 0) | 867 | if (strcmp(refsymname, *s) == 0) |
758 | return 1; | 868 | return 1; |
759 | 869 | ||
760 | /* Check for pattern 5 */ | ||
761 | if (strrcmp(tosec, ".text") == 0) | ||
762 | len = strlen(tosec) - strlen(".text"); | ||
763 | else | ||
764 | len = strlen(tosec); | ||
765 | if ((strncmp(tosec, fromsec, len) == 0) && (strlen(fromsec) > len) && | ||
766 | (strcmp(fromsec + len, ".literal") == 0)) | ||
767 | return 1; | ||
768 | |||
769 | return 0; | 870 | return 0; |
770 | } | 871 | } |
771 | 872 | ||
@@ -1011,8 +1112,7 @@ static int addend_mips_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) | |||
1011 | } | 1112 | } |
1012 | 1113 | ||
1013 | static void section_rela(const char *modname, struct elf_info *elf, | 1114 | static void section_rela(const char *modname, struct elf_info *elf, |
1014 | Elf_Shdr *sechdr, int section(const char *), | 1115 | Elf_Shdr *sechdr) |
1015 | int section_ref_ok(const char *)) | ||
1016 | { | 1116 | { |
1017 | Elf_Sym *sym; | 1117 | Elf_Sym *sym; |
1018 | Elf_Rela *rela; | 1118 | Elf_Rela *rela; |
@@ -1031,7 +1131,7 @@ static void section_rela(const char *modname, struct elf_info *elf, | |||
1031 | fromsec = secstrings + sechdr->sh_name; | 1131 | fromsec = secstrings + sechdr->sh_name; |
1032 | fromsec += strlen(".rela"); | 1132 | fromsec += strlen(".rela"); |
1033 | /* if from section (name) is know good then skip it */ | 1133 | /* if from section (name) is know good then skip it */ |
1034 | if (section_ref_ok(fromsec)) | 1134 | if (match(fromsec, section_white_list)) |
1035 | return; | 1135 | return; |
1036 | 1136 | ||
1037 | for (rela = start; rela < stop; rela++) { | 1137 | for (rela = start; rela < stop; rela++) { |
@@ -1059,14 +1159,13 @@ static void section_rela(const char *modname, struct elf_info *elf, | |||
1059 | 1159 | ||
1060 | tosec = secstrings + | 1160 | tosec = secstrings + |
1061 | elf->sechdrs[sym->st_shndx].sh_name; | 1161 | elf->sechdrs[sym->st_shndx].sh_name; |
1062 | if (section(tosec)) | 1162 | if (section_mismatch(fromsec, tosec)) |
1063 | warn_sec_mismatch(modname, fromsec, elf, sym, r); | 1163 | warn_sec_mismatch(modname, fromsec, elf, sym, r); |
1064 | } | 1164 | } |
1065 | } | 1165 | } |
1066 | 1166 | ||
1067 | static void section_rel(const char *modname, struct elf_info *elf, | 1167 | static void section_rel(const char *modname, struct elf_info *elf, |
1068 | Elf_Shdr *sechdr, int section(const char *), | 1168 | Elf_Shdr *sechdr) |
1069 | int section_ref_ok(const char *)) | ||
1070 | { | 1169 | { |
1071 | Elf_Sym *sym; | 1170 | Elf_Sym *sym; |
1072 | Elf_Rel *rel; | 1171 | Elf_Rel *rel; |
@@ -1085,7 +1184,7 @@ static void section_rel(const char *modname, struct elf_info *elf, | |||
1085 | fromsec = secstrings + sechdr->sh_name; | 1184 | fromsec = secstrings + sechdr->sh_name; |
1086 | fromsec += strlen(".rel"); | 1185 | fromsec += strlen(".rel"); |
1087 | /* if from section (name) is know good then skip it */ | 1186 | /* if from section (name) is know good then skip it */ |
1088 | if (section_ref_ok(fromsec)) | 1187 | if (match(fromsec, section_white_list)) |
1089 | return; | 1188 | return; |
1090 | 1189 | ||
1091 | for (rel = start; rel < stop; rel++) { | 1190 | for (rel = start; rel < stop; rel++) { |
@@ -1127,7 +1226,7 @@ static void section_rel(const char *modname, struct elf_info *elf, | |||
1127 | 1226 | ||
1128 | tosec = secstrings + | 1227 | tosec = secstrings + |
1129 | elf->sechdrs[sym->st_shndx].sh_name; | 1228 | elf->sechdrs[sym->st_shndx].sh_name; |
1130 | if (section(tosec)) | 1229 | if (section_mismatch(fromsec, tosec)) |
1131 | warn_sec_mismatch(modname, fromsec, elf, sym, r); | 1230 | warn_sec_mismatch(modname, fromsec, elf, sym, r); |
1132 | } | 1231 | } |
1133 | } | 1232 | } |
@@ -1145,9 +1244,7 @@ static void section_rel(const char *modname, struct elf_info *elf, | |||
1145 | * be discarded and warns about it. | 1244 | * be discarded and warns about it. |
1146 | **/ | 1245 | **/ |
1147 | static void check_sec_ref(struct module *mod, const char *modname, | 1246 | static void check_sec_ref(struct module *mod, const char *modname, |
1148 | struct elf_info *elf, | 1247 | struct elf_info *elf) |
1149 | int section(const char *), | ||
1150 | int section_ref_ok(const char *)) | ||
1151 | { | 1248 | { |
1152 | int i; | 1249 | int i; |
1153 | Elf_Ehdr *hdr = elf->hdr; | 1250 | Elf_Ehdr *hdr = elf->hdr; |
@@ -1157,156 +1254,12 @@ static void check_sec_ref(struct module *mod, const char *modname, | |||
1157 | for (i = 0; i < hdr->e_shnum; i++) { | 1254 | for (i = 0; i < hdr->e_shnum; i++) { |
1158 | /* We want to process only relocation sections and not .init */ | 1255 | /* We want to process only relocation sections and not .init */ |
1159 | if (sechdrs[i].sh_type == SHT_RELA) | 1256 | if (sechdrs[i].sh_type == SHT_RELA) |
1160 | section_rela(modname, elf, &elf->sechdrs[i], | 1257 | section_rela(modname, elf, &elf->sechdrs[i]); |
1161 | section, section_ref_ok); | ||
1162 | else if (sechdrs[i].sh_type == SHT_REL) | 1258 | else if (sechdrs[i].sh_type == SHT_REL) |
1163 | section_rel(modname, elf, &elf->sechdrs[i], | 1259 | section_rel(modname, elf, &elf->sechdrs[i]); |
1164 | section, section_ref_ok); | ||
1165 | } | 1260 | } |
1166 | } | 1261 | } |
1167 | 1262 | ||
1168 | /* | ||
1169 | * Identify sections from which references to either a | ||
1170 | * .init or a .exit section is OK. | ||
1171 | * | ||
1172 | * [OPD] Keith Ownes <kaos@sgi.com> commented: | ||
1173 | * For our future {in}sanity, add a comment that this is the ppc .opd | ||
1174 | * section, not the ia64 .opd section. | ||
1175 | * ia64 .opd should not point to discarded sections. | ||
1176 | * [.rodata] like for .init.text we ignore .rodata references -same reason | ||
1177 | */ | ||
1178 | static int initexit_section_ref_ok(const char *name) | ||
1179 | { | ||
1180 | const char **s; | ||
1181 | /* Absolute section names */ | ||
1182 | const char *namelist1[] = { | ||
1183 | "__bug_table", /* used by powerpc for BUG() */ | ||
1184 | "__ex_table", | ||
1185 | ".altinstructions", | ||
1186 | ".cranges", /* used by sh64 */ | ||
1187 | ".fixup", | ||
1188 | ".machvec", /* ia64 + powerpc uses these */ | ||
1189 | ".machine.desc", | ||
1190 | ".opd", /* See comment [OPD] */ | ||
1191 | "__dbe_table", | ||
1192 | ".parainstructions", | ||
1193 | ".pdr", | ||
1194 | ".plt", /* seen on ARCH=um build on x86_64. Harmless */ | ||
1195 | ".smp_locks", | ||
1196 | ".stab", | ||
1197 | ".m68k_fixup", | ||
1198 | ".xt.prop", /* xtensa informational section */ | ||
1199 | ".xt.lit", /* xtensa informational section */ | ||
1200 | NULL | ||
1201 | }; | ||
1202 | /* Start of section names */ | ||
1203 | const char *namelist2[] = { | ||
1204 | ".debug", | ||
1205 | ".eh_frame", | ||
1206 | ".note", /* ignore ELF notes - may contain anything */ | ||
1207 | ".got", /* powerpc - global offset table */ | ||
1208 | ".toc", /* powerpc - table of contents */ | ||
1209 | NULL | ||
1210 | }; | ||
1211 | /* part of section name */ | ||
1212 | const char *namelist3 [] = { | ||
1213 | ".unwind", /* Sample: IA_64.unwind.exit.text */ | ||
1214 | NULL | ||
1215 | }; | ||
1216 | |||
1217 | for (s = namelist1; *s; s++) | ||
1218 | if (strcmp(*s, name) == 0) | ||
1219 | return 1; | ||
1220 | for (s = namelist2; *s; s++) | ||
1221 | if (strncmp(*s, name, strlen(*s)) == 0) | ||
1222 | return 1; | ||
1223 | for (s = namelist3; *s; s++) | ||
1224 | if (strstr(name, *s) != NULL) | ||
1225 | return 1; | ||
1226 | return 0; | ||
1227 | } | ||
1228 | |||
1229 | |||
1230 | /* | ||
1231 | * Identify sections from which references to a .init section is OK. | ||
1232 | * | ||
1233 | * Unfortunately references to read only data that referenced .init | ||
1234 | * sections had to be excluded. Almost all of these are false | ||
1235 | * positives, they are created by gcc. The downside of excluding rodata | ||
1236 | * is that there really are some user references from rodata to | ||
1237 | * init code, e.g. drivers/video/vgacon.c: | ||
1238 | * | ||
1239 | * const struct consw vga_con = { | ||
1240 | * con_startup: vgacon_startup, | ||
1241 | * | ||
1242 | * where vgacon_startup is __init. If you want to wade through the false | ||
1243 | * positives, take out the check for rodata. | ||
1244 | */ | ||
1245 | static int init_section_ref_ok(const char *name) | ||
1246 | { | ||
1247 | const char **s; | ||
1248 | /* Absolute section names */ | ||
1249 | const char *namelist1[] = { | ||
1250 | "__dbe_table", /* MIPS generate these */ | ||
1251 | "__ftr_fixup", /* powerpc cpu feature fixup */ | ||
1252 | "__fw_ftr_fixup", /* powerpc firmware feature fixup */ | ||
1253 | "__param", | ||
1254 | ".data.rel.ro", /* used by parisc64 */ | ||
1255 | ".init", | ||
1256 | ".text.lock", | ||
1257 | NULL | ||
1258 | }; | ||
1259 | /* Start of section names */ | ||
1260 | const char *namelist2[] = { | ||
1261 | ".init.", | ||
1262 | ".pci_fixup", | ||
1263 | ".rodata", | ||
1264 | NULL | ||
1265 | }; | ||
1266 | |||
1267 | if (initexit_section_ref_ok(name)) | ||
1268 | return 1; | ||
1269 | |||
1270 | for (s = namelist1; *s; s++) | ||
1271 | if (strcmp(*s, name) == 0) | ||
1272 | return 1; | ||
1273 | for (s = namelist2; *s; s++) | ||
1274 | if (strncmp(*s, name, strlen(*s)) == 0) | ||
1275 | return 1; | ||
1276 | |||
1277 | /* If section name ends with ".init" we allow references | ||
1278 | * as is the case with .initcallN.init, .early_param.init, | ||
1279 | * .taglist.init etc | ||
1280 | */ | ||
1281 | if (strrcmp(name, ".init") == 0) | ||
1282 | return 1; | ||
1283 | return 0; | ||
1284 | } | ||
1285 | |||
1286 | /* | ||
1287 | * Identify sections from which references to a .exit section is OK. | ||
1288 | */ | ||
1289 | static int exit_section_ref_ok(const char *name) | ||
1290 | { | ||
1291 | const char **s; | ||
1292 | /* Absolute section names */ | ||
1293 | const char *namelist1[] = { | ||
1294 | ".exit.data", | ||
1295 | ".exit.text", | ||
1296 | ".exitcall.exit", | ||
1297 | ".rodata", | ||
1298 | NULL | ||
1299 | }; | ||
1300 | |||
1301 | if (initexit_section_ref_ok(name)) | ||
1302 | return 1; | ||
1303 | |||
1304 | for (s = namelist1; *s; s++) | ||
1305 | if (strcmp(*s, name) == 0) | ||
1306 | return 1; | ||
1307 | return 0; | ||
1308 | } | ||
1309 | |||
1310 | static void read_symbols(char *modname) | 1263 | static void read_symbols(char *modname) |
1311 | { | 1264 | { |
1312 | const char *symname; | 1265 | const char *symname; |
@@ -1347,10 +1300,8 @@ static void read_symbols(char *modname) | |||
1347 | handle_moddevtable(mod, &info, sym, symname); | 1300 | handle_moddevtable(mod, &info, sym, symname); |
1348 | } | 1301 | } |
1349 | if (!is_vmlinux(modname) || | 1302 | if (!is_vmlinux(modname) || |
1350 | (is_vmlinux(modname) && vmlinux_section_warnings)) { | 1303 | (is_vmlinux(modname) && vmlinux_section_warnings)) |
1351 | check_sec_ref(mod, modname, &info, init_section, init_section_ref_ok); | 1304 | check_sec_ref(mod, modname, &info); |
1352 | check_sec_ref(mod, modname, &info, exit_section, exit_section_ref_ok); | ||
1353 | } | ||
1354 | 1305 | ||
1355 | version = get_modinfo(info.modinfo, info.modinfo_len, "version"); | 1306 | version = get_modinfo(info.modinfo, info.modinfo_len, "version"); |
1356 | if (version) | 1307 | if (version) |