diff options
Diffstat (limited to 'scripts/mod')
-rw-r--r-- | scripts/mod/modpost.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index e26381e3fc00..47bef62eecd7 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
@@ -582,9 +582,19 @@ static int strrcmp(const char *s, const char *sub) | |||
582 | * tosec = .init.text | .exit.text | .init.data | 582 | * tosec = .init.text | .exit.text | .init.data |
583 | * fromsec = .data | 583 | * fromsec = .data |
584 | * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one | 584 | * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one |
585 | * | ||
586 | * Pattern 3: | ||
587 | * Some symbols belong to init section but still it is ok to reference | ||
588 | * these from non-init sections as these symbols don't have any memory | ||
589 | * allocated for them and symbol address and value are same. So even | ||
590 | * if init section is freed, its ok to reference those symbols. | ||
591 | * For ex. symbols marking the init section boundaries. | ||
592 | * This pattern is identified by | ||
593 | * refsymname = __init_begin, _sinittext, _einittext | ||
585 | **/ | 594 | **/ |
586 | static int secref_whitelist(const char *modname, const char *tosec, | 595 | static int secref_whitelist(const char *modname, const char *tosec, |
587 | const char *fromsec, const char *atsym) | 596 | const char *fromsec, const char *atsym, |
597 | const char *refsymname) | ||
588 | { | 598 | { |
589 | int f1 = 1, f2 = 1; | 599 | int f1 = 1, f2 = 1; |
590 | const char **s; | 600 | const char **s; |
@@ -595,6 +605,14 @@ static int secref_whitelist(const char *modname, const char *tosec, | |||
595 | "_ops", | 605 | "_ops", |
596 | "_probe", | 606 | "_probe", |
597 | "_probe_one", | 607 | "_probe_one", |
608 | "_console", | ||
609 | NULL | ||
610 | }; | ||
611 | |||
612 | const char *pat3refsym[] = { | ||
613 | "__init_begin", | ||
614 | "_sinittext", | ||
615 | "_einittext", | ||
598 | NULL | 616 | NULL |
599 | }; | 617 | }; |
600 | 618 | ||
@@ -628,6 +646,11 @@ static int secref_whitelist(const char *modname, const char *tosec, | |||
628 | if ((strcmp(fromsec, ".pci_fixup") == 0) && | 646 | if ((strcmp(fromsec, ".pci_fixup") == 0) && |
629 | (strcmp(tosec, ".init.text") == 0)) | 647 | (strcmp(tosec, ".init.text") == 0)) |
630 | return 1; | 648 | return 1; |
649 | |||
650 | /* Check for pattern 3 */ | ||
651 | for (s = pat3refsym; *s; s++) | ||
652 | if (strcmp(refsymname, *s) == 0) | ||
653 | return 1; | ||
631 | } | 654 | } |
632 | return 0; | 655 | return 0; |
633 | } | 656 | } |
@@ -737,7 +760,7 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec, | |||
737 | /* check whitelist - we may ignore it */ | 760 | /* check whitelist - we may ignore it */ |
738 | if (before && | 761 | if (before && |
739 | secref_whitelist(modname, secname, fromsec, | 762 | secref_whitelist(modname, secname, fromsec, |
740 | elf->strtab + before->st_name)) | 763 | elf->strtab + before->st_name, refsymname)) |
741 | return; | 764 | return; |
742 | 765 | ||
743 | if (before && after) { | 766 | if (before && after) { |
@@ -998,6 +1021,7 @@ static int exit_section_ref_ok(const char *name) | |||
998 | "__bug_table", /* used by powerpc for BUG() */ | 1021 | "__bug_table", /* used by powerpc for BUG() */ |
999 | ".exitcall.exit", | 1022 | ".exitcall.exit", |
1000 | ".eh_frame", | 1023 | ".eh_frame", |
1024 | ".parainstructions", | ||
1001 | ".stab", | 1025 | ".stab", |
1002 | "__ex_table", | 1026 | "__ex_table", |
1003 | ".fixup", | 1027 | ".fixup", |