aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/mod
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-25 18:49:59 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-25 18:49:59 -0400
commit6a28a05f9b1b4db920e390ac89968ed6d2e4b8ec (patch)
treedc3f5c5a87bd9fa969e281cbbfcc85ca373398cf /scripts/mod
parent4bf3b0bc3e98f77de88b336fd8d673649601b557 (diff)
parentcb7e51d8b1f8e2390970f4bb7d095c414b1bf3cf (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild
* git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild: kbuild: fix modpost warnings for xtensa kbuild: be more foregiving on init section naming kbuild: rearrange a few function in modpost kbuild: use LDFLAGS_MODULE only for .ko links kconfig: remove unused members from struct symbol kconfig: attach help text to menus kbuild: fix up printing of Linux C Library version in scripts/ver_linux kbuild: do not do section mismatch checks on vmlinux in 2nd pass
Diffstat (limited to 'scripts/mod')
-rw-r--r--scripts/mod/modpost.c159
1 files changed, 92 insertions, 67 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 5ab7914d30ef..ee58ded021d7 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -23,6 +23,8 @@ int have_vmlinux = 0;
23static int all_versions = 0; 23static int all_versions = 0;
24/* If we are modposting external module set to 1 */ 24/* If we are modposting external module set to 1 */
25static int external_module = 0; 25static int external_module = 0;
26/* Warn about section mismatch in vmlinux if set to 1 */
27static int vmlinux_section_warnings = 1;
26/* Only warn about unresolved symbols */ 28/* Only warn about unresolved symbols */
27static int warn_unresolved = 0; 29static int warn_unresolved = 0;
28/* How a symbol is exported */ 30/* How a symbol is exported */
@@ -584,13 +586,61 @@ static int strrcmp(const char *s, const char *sub)
584 return memcmp(s + slen - sublen, sub, sublen); 586 return memcmp(s + slen - sublen, sub, sublen);
585} 587}
586 588
589/*
590 * Functions used only during module init is marked __init and is stored in
591 * a .init.text section. Likewise data is marked __initdata and stored in
592 * a .init.data section.
593 * If this section is one of these sections return 1
594 * See include/linux/init.h for the details
595 */
596static int init_section(const char *name)
597{
598 if (strcmp(name, ".init") == 0)
599 return 1;
600 if (strncmp(name, ".init.", strlen(".init.")) == 0)
601 return 1;
602 return 0;
603}
604
605/*
606 * Functions used only during module exit is marked __exit and is stored in
607 * a .exit.text section. Likewise data is marked __exitdata and stored in
608 * a .exit.data section.
609 * If this section is one of these sections return 1
610 * See include/linux/init.h for the details
611 **/
612static int exit_section(const char *name)
613{
614 if (strcmp(name, ".exit.text") == 0)
615 return 1;
616 if (strcmp(name, ".exit.data") == 0)
617 return 1;
618 return 0;
619
620}
621
622/*
623 * Data sections are named like this:
624 * .data | .data.rel | .data.rel.*
625 * Return 1 if the specified section is a data section
626 */
627static int data_section(const char *name)
628{
629 if ((strcmp(name, ".data") == 0) ||
630 (strcmp(name, ".data.rel") == 0) ||
631 (strncmp(name, ".data.rel.", strlen(".data.rel.")) == 0))
632 return 1;
633 else
634 return 0;
635}
636
587/** 637/**
588 * Whitelist to allow certain references to pass with no warning. 638 * Whitelist to allow certain references to pass with no warning.
589 * 639 *
590 * Pattern 0: 640 * Pattern 0:
591 * Do not warn if funtion/data are marked with __init_refok/__initdata_refok. 641 * Do not warn if funtion/data are marked with __init_refok/__initdata_refok.
592 * The pattern is identified by: 642 * The pattern is identified by:
593 * fromsec = .text.init.refok | .data.init.refok 643 * fromsec = .text.init.refok* | .data.init.refok*
594 * 644 *
595 * Pattern 1: 645 * Pattern 1:
596 * If a module parameter is declared __initdata and permissions=0 646 * If a module parameter is declared __initdata and permissions=0
@@ -608,8 +658,8 @@ static int strrcmp(const char *s, const char *sub)
608 * These functions may often be marked __init and we do not want to 658 * These functions may often be marked __init and we do not want to
609 * warn here. 659 * warn here.
610 * the pattern is identified by: 660 * the pattern is identified by:
611 * tosec = .init.text | .exit.text | .init.data 661 * tosec = init or exit section
612 * fromsec = .data | .data.rel | .data.rel.* 662 * fromsec = data section
613 * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one, *_console, *_timer 663 * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one, *_console, *_timer
614 * 664 *
615 * Pattern 3: 665 * Pattern 3:
@@ -625,12 +675,18 @@ static int strrcmp(const char *s, const char *sub)
625 * This pattern is identified by 675 * This pattern is identified by
626 * refsymname = __init_begin, _sinittext, _einittext 676 * refsymname = __init_begin, _sinittext, _einittext
627 * 677 *
678 * Pattern 5:
679 * Xtensa uses literal sections for constants that are accessed PC-relative.
680 * Literal sections may safely reference their text sections.
681 * (Note that the name for the literal section omits any trailing '.text')
682 * tosec = <section>[.text]
683 * fromsec = <section>.literal
628 **/ 684 **/
629static int secref_whitelist(const char *modname, const char *tosec, 685static int secref_whitelist(const char *modname, const char *tosec,
630 const char *fromsec, const char *atsym, 686 const char *fromsec, const char *atsym,
631 const char *refsymname) 687 const char *refsymname)
632{ 688{
633 int f1 = 1, f2 = 1; 689 int len;
634 const char **s; 690 const char **s;
635 const char *pat2sym[] = { 691 const char *pat2sym[] = {
636 "driver", 692 "driver",
@@ -652,36 +708,21 @@ static int secref_whitelist(const char *modname, const char *tosec,
652 }; 708 };
653 709
654 /* Check for pattern 0 */ 710 /* Check for pattern 0 */
655 if ((strcmp(fromsec, ".text.init.refok") == 0) || 711 if ((strncmp(fromsec, ".text.init.refok", strlen(".text.init.refok")) == 0) ||
656 (strcmp(fromsec, ".data.init.refok") == 0)) 712 (strncmp(fromsec, ".data.init.refok", strlen(".data.init.refok")) == 0))
657 return 1; 713 return 1;
658 714
659 /* Check for pattern 1 */ 715 /* Check for pattern 1 */
660 if (strcmp(tosec, ".init.data") != 0) 716 if ((strcmp(tosec, ".init.data") == 0) &&
661 f1 = 0; 717 (strncmp(fromsec, ".data", strlen(".data")) == 0) &&
662 if (strncmp(fromsec, ".data", strlen(".data")) != 0) 718 (strncmp(atsym, "__param", strlen("__param")) == 0))
663 f1 = 0; 719 return 1;
664 if (strncmp(atsym, "__param", strlen("__param")) != 0)
665 f1 = 0;
666
667 if (f1)
668 return f1;
669 720
670 /* Check for pattern 2 */ 721 /* Check for pattern 2 */
671 if ((strcmp(tosec, ".init.text") != 0) && 722 if ((init_section(tosec) || exit_section(tosec)) && data_section(fromsec))
672 (strcmp(tosec, ".exit.text") != 0) && 723 for (s = pat2sym; *s; s++)
673 (strcmp(tosec, ".init.data") != 0)) 724 if (strrcmp(atsym, *s) == 0)
674 f2 = 0; 725 return 1;
675 if ((strcmp(fromsec, ".data") != 0) &&
676 (strcmp(fromsec, ".data.rel") != 0) &&
677 (strncmp(fromsec, ".data.rel.", strlen(".data.rel.")) != 0))
678 f2 = 0;
679
680 for (s = pat2sym; *s; s++)
681 if (strrcmp(atsym, *s) == 0)
682 f1 = 1;
683 if (f1 && f2)
684 return 1;
685 726
686 /* Check for pattern 3 */ 727 /* Check for pattern 3 */
687 if ((strcmp(fromsec, ".text.head") == 0) && 728 if ((strcmp(fromsec, ".text.head") == 0) &&
@@ -694,6 +735,15 @@ static int secref_whitelist(const char *modname, const char *tosec,
694 if (strcmp(refsymname, *s) == 0) 735 if (strcmp(refsymname, *s) == 0)
695 return 1; 736 return 1;
696 737
738 /* Check for pattern 5 */
739 if (strrcmp(tosec, ".text") == 0)
740 len = strlen(tosec) - strlen(".text");
741 else
742 len = strlen(tosec);
743 if ((strncmp(tosec, fromsec, len) == 0) && (strlen(fromsec) > len) &&
744 (strcmp(fromsec + len, ".literal") == 0))
745 return 1;
746
697 return 0; 747 return 0;
698} 748}
699 749
@@ -822,9 +872,9 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec,
822 refsymname = elf->strtab + refsym->st_name; 872 refsymname = elf->strtab + refsym->st_name;
823 873
824 /* check whitelist - we may ignore it */ 874 /* check whitelist - we may ignore it */
825 if (before && 875 if (secref_whitelist(modname, secname, fromsec,
826 secref_whitelist(modname, secname, fromsec, 876 before ? elf->strtab + before->st_name : "",
827 elf->strtab + before->st_name, refsymname)) 877 refsymname))
828 return; 878 return;
829 879
830 if (before && after) { 880 if (before && after) {
@@ -1077,6 +1127,8 @@ static int initexit_section_ref_ok(const char *name)
1077 ".smp_locks", 1127 ".smp_locks",
1078 ".stab", 1128 ".stab",
1079 ".m68k_fixup", 1129 ".m68k_fixup",
1130 ".xt.prop", /* xtensa informational section */
1131 ".xt.lit", /* xtensa informational section */
1080 NULL 1132 NULL
1081 }; 1133 };
1082 /* Start of section names */ 1134 /* Start of section names */
@@ -1106,21 +1158,6 @@ static int initexit_section_ref_ok(const char *name)
1106 return 0; 1158 return 0;
1107} 1159}
1108 1160
1109/**
1110 * Functions used only during module init is marked __init and is stored in
1111 * a .init.text section. Likewise data is marked __initdata and stored in
1112 * a .init.data section.
1113 * If this section is one of these sections return 1
1114 * See include/linux/init.h for the details
1115 **/
1116static int init_section(const char *name)
1117{
1118 if (strcmp(name, ".init") == 0)
1119 return 1;
1120 if (strncmp(name, ".init.", strlen(".init.")) == 0)
1121 return 1;
1122 return 0;
1123}
1124 1161
1125/* 1162/*
1126 * Identify sections from which references to a .init section is OK. 1163 * Identify sections from which references to a .init section is OK.
@@ -1178,23 +1215,6 @@ static int init_section_ref_ok(const char *name)
1178} 1215}
1179 1216
1180/* 1217/*
1181 * Functions used only during module exit is marked __exit and is stored in
1182 * a .exit.text section. Likewise data is marked __exitdata and stored in
1183 * a .exit.data section.
1184 * If this section is one of these sections return 1
1185 * See include/linux/init.h for the details
1186 **/
1187static int exit_section(const char *name)
1188{
1189 if (strcmp(name, ".exit.text") == 0)
1190 return 1;
1191 if (strcmp(name, ".exit.data") == 0)
1192 return 1;
1193 return 0;
1194
1195}
1196
1197/*
1198 * Identify sections from which references to a .exit section is OK. 1218 * Identify sections from which references to a .exit section is OK.
1199 */ 1219 */
1200static int exit_section_ref_ok(const char *name) 1220static int exit_section_ref_ok(const char *name)
@@ -1257,8 +1277,10 @@ static void read_symbols(char *modname)
1257 handle_modversions(mod, &info, sym, symname); 1277 handle_modversions(mod, &info, sym, symname);
1258 handle_moddevtable(mod, &info, sym, symname); 1278 handle_moddevtable(mod, &info, sym, symname);
1259 } 1279 }
1260 check_sec_ref(mod, modname, &info, init_section, init_section_ref_ok); 1280 if (is_vmlinux(modname) && vmlinux_section_warnings) {
1261 check_sec_ref(mod, modname, &info, exit_section, exit_section_ref_ok); 1281 check_sec_ref(mod, modname, &info, init_section, init_section_ref_ok);
1282 check_sec_ref(mod, modname, &info, exit_section, exit_section_ref_ok);
1283 }
1262 1284
1263 version = get_modinfo(info.modinfo, info.modinfo_len, "version"); 1285 version = get_modinfo(info.modinfo, info.modinfo_len, "version");
1264 if (version) 1286 if (version)
@@ -1626,7 +1648,7 @@ int main(int argc, char **argv)
1626 int opt; 1648 int opt;
1627 int err; 1649 int err;
1628 1650
1629 while ((opt = getopt(argc, argv, "i:I:mo:aw")) != -1) { 1651 while ((opt = getopt(argc, argv, "i:I:mso:aw")) != -1) {
1630 switch(opt) { 1652 switch(opt) {
1631 case 'i': 1653 case 'i':
1632 kernel_read = optarg; 1654 kernel_read = optarg;
@@ -1644,6 +1666,9 @@ int main(int argc, char **argv)
1644 case 'a': 1666 case 'a':
1645 all_versions = 1; 1667 all_versions = 1;
1646 break; 1668 break;
1669 case 's':
1670 vmlinux_section_warnings = 0;
1671 break;
1647 case 'w': 1672 case 'w':
1648 warn_unresolved = 1; 1673 warn_unresolved = 1;
1649 break; 1674 break;