summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorPaul Gortmaker <paul.gortmaker@windriver.com>2015-04-20 10:20:40 +0930
committerBen Hutchings <ben@decadent.org.uk>2017-11-11 13:33:42 +0000
commit89df4c05e38b84213ce370c1b45fb88f97a25c9c (patch)
treeb48c4a70b67e76783d49ecdd39aca789539dabca /scripts
parenta74cbb37bb2fe6a700eba93000347b12659bc844 (diff)
downloadlinux-stable-89df4c05e38b84213ce370c1b45fb88f97a25c9c.tar.gz
linux-stable-89df4c05e38b84213ce370c1b45fb88f97a25c9c.tar.bz2
linux-stable-89df4c05e38b84213ce370c1b45fb88f97a25c9c.zip
modpost: don't emit section mismatch warnings for compiler optimizations
commit 4a3893d069b788f3570c19c12d9e986e8e15870f upstream. Currently an allyesconfig build [gcc-4.9.1] can generate the following: WARNING: vmlinux.o(.text.unlikely+0x3864): Section mismatch in reference from the function cpumask_empty.constprop.3() to the variable .init.data:nmi_ipi_mask which comes from the cpumask_empty usage in arch/x86/kernel/nmi_selftest.c. Normally we would not see a symbol entry for cpumask_empty since it is: static inline bool cpumask_empty(const struct cpumask *srcp) however in this case, the variant of the symbol gets emitted when GCC does constant propagation optimization. Fix things up so that any locally optimized constprop variants don't warn when accessing variables that live in the __init sections. [arnd: adapted text_sections definition to 3.18] Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/mod/modpost.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 14e3f53ebf17..2241d036b63a 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -930,6 +930,10 @@ static const char *init_sections[] = { ALL_INIT_SECTIONS, NULL };
static const char *init_exit_sections[] =
{ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL };
+/* all text sections */
+static const char *const text_sections[] = { ALL_INIT_TEXT_SECTIONS,
+ ALL_EXIT_TEXT_SECTIONS, TEXT_SECTIONS, NULL };
+
/* data section */
static const char *data_sections[] = { DATA_SECTIONS, NULL };
@@ -948,6 +952,7 @@ static const char *data_sections[] = { DATA_SECTIONS, NULL };
static const char *head_sections[] = { ".head.text*", NULL };
static const char *linker_symbols[] =
{ "__init_begin", "_sinittext", "_einittext", NULL };
+static const char *const optim_symbols[] = { "*.constprop.*", NULL };
enum mismatch {
TEXT_TO_ANY_INIT,
@@ -1105,6 +1110,17 @@ static const struct sectioncheck *section_mismatch(
* This pattern is identified by
* refsymname = __init_begin, _sinittext, _einittext
*
+ * Pattern 5:
+ * GCC may optimize static inlines when fed constant arg(s) resulting
+ * in functions like cpumask_empty() -- generating an associated symbol
+ * cpumask_empty.constprop.3 that appears in the audit. If the const that
+ * is passed in comes from __init, like say nmi_ipi_mask, we get a
+ * meaningless section warning. May need to add isra symbols too...
+ * This pattern is identified by
+ * tosec = init section
+ * fromsec = text section
+ * refsymname = *.constprop.*
+ *
**/
static int secref_whitelist(const struct sectioncheck *mismatch,
const char *fromsec, const char *fromsym,
@@ -1137,6 +1153,12 @@ static int secref_whitelist(const struct sectioncheck *mismatch,
if (match(tosym, linker_symbols))
return 0;
+ /* Check for pattern 5 */
+ if (match(fromsec, text_sections) &&
+ match(tosec, init_sections) &&
+ match(fromsym, optim_symbols))
+ return 0;
+
return 1;
}