diff options
-rw-r--r-- | scripts/mod/modpost.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 82e019bf2dc5..2aa47623f5f8 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; |
@@ -599,6 +609,13 @@ static int secref_whitelist(const char *modname, const char *tosec, | |||
599 | NULL | 609 | NULL |
600 | }; | 610 | }; |
601 | 611 | ||
612 | const char *pat3refsym[] = { | ||
613 | "__init_begin", | ||
614 | "_sinittext", | ||
615 | "_einittext", | ||
616 | NULL | ||
617 | }; | ||
618 | |||
602 | /* Check for pattern 1 */ | 619 | /* Check for pattern 1 */ |
603 | if (strcmp(tosec, ".init.data") != 0) | 620 | if (strcmp(tosec, ".init.data") != 0) |
604 | f1 = 0; | 621 | f1 = 0; |
@@ -629,6 +646,11 @@ static int secref_whitelist(const char *modname, const char *tosec, | |||
629 | if ((strcmp(fromsec, ".pci_fixup") == 0) && | 646 | if ((strcmp(fromsec, ".pci_fixup") == 0) && |
630 | (strcmp(tosec, ".init.text") == 0)) | 647 | (strcmp(tosec, ".init.text") == 0)) |
631 | 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; | ||
632 | } | 654 | } |
633 | return 0; | 655 | return 0; |
634 | } | 656 | } |
@@ -738,7 +760,7 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec, | |||
738 | /* check whitelist - we may ignore it */ | 760 | /* check whitelist - we may ignore it */ |
739 | if (before && | 761 | if (before && |
740 | secref_whitelist(modname, secname, fromsec, | 762 | secref_whitelist(modname, secname, fromsec, |
741 | elf->strtab + before->st_name)) | 763 | elf->strtab + before->st_name, refsymname)) |
742 | return; | 764 | return; |
743 | 765 | ||
744 | if (before && after) { | 766 | if (before && after) { |