aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorSam Ravnborg <sam@ravnborg.org>2008-01-13 16:21:31 -0500
committerSam Ravnborg <sam@ravnborg.org>2008-01-28 17:14:40 -0500
commit10668220a97cb8b3fa1011a252175737ba750d51 (patch)
treed188c01135c3a1d23560616336a3c19dade98296 /scripts
parent5b24c0715fc4c71e60e9a684248cc49d62dfa900 (diff)
kbuild: introduce blacklisting in modpost
Change the logic in modpost so we identify all the bad combinations of sections that refer to other sections. Compared to the previous approach we are much less dependent on knowledge of what additional sections the tool chain uses and thus we can keep the false positives low. The implmentation is changed to use a table based lookup and we now check all combinations in first pass so we no longer need separate passes for init and exit sections. Tested that the same warnings are generated for an allyesconfig build without CONFIG_HOTPLUG. Signed-off-by: Sam Ravnborg <sam@ravnborg.org> Cc: Randy Dunlap <randy.dunlap@oracle.com> Cc: Adrian Bunk <bunk@kernel.org>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/mod/modpost.c305
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 */
612static 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 */
634int 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 */
712static 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
727struct sectioncheck {
728 const char *fromsec[20];
729 const char *tosec[20];
730};
731
732const 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
757static 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 = &sectioncheck[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 **/
705static int secref_whitelist(const char *modname, const char *tosec, 816static 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
1013static void section_rela(const char *modname, struct elf_info *elf, 1114static 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
1067static void section_rel(const char *modname, struct elf_info *elf, 1167static 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 **/
1147static void check_sec_ref(struct module *mod, const char *modname, 1246static 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 */
1178static 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 */
1245static 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 */
1289static 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
1310static void read_symbols(char *modname) 1263static 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)