Commit 4a3893d0 authored by Paul Gortmaker's avatar Paul Gortmaker Committed by Rusty Russell

modpost: don't emit section mismatch warnings for compiler optimizations

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.
Signed-off-by: default avatarPaul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent 09c20c03
...@@ -908,6 +908,9 @@ static const char *const init_sections[] = { ALL_INIT_SECTIONS, NULL }; ...@@ -908,6 +908,9 @@ static const char *const init_sections[] = { ALL_INIT_SECTIONS, NULL };
static const char *const init_exit_sections[] = static const char *const init_exit_sections[] =
{ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL }; {ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL };
/* all text sections */
static const char *const text_sections[] = { ALL_TEXT_SECTIONS, NULL };
/* data section */ /* data section */
static const char *const data_sections[] = { DATA_SECTIONS, NULL }; static const char *const data_sections[] = { DATA_SECTIONS, NULL };
...@@ -926,6 +929,7 @@ static const char *const data_sections[] = { DATA_SECTIONS, NULL }; ...@@ -926,6 +929,7 @@ static const char *const data_sections[] = { DATA_SECTIONS, NULL };
static const char *const head_sections[] = { ".head.text*", NULL }; static const char *const head_sections[] = { ".head.text*", NULL };
static const char *const linker_symbols[] = static const char *const linker_symbols[] =
{ "__init_begin", "_sinittext", "_einittext", NULL }; { "__init_begin", "_sinittext", "_einittext", NULL };
static const char *const optim_symbols[] = { "*.constprop.*", NULL };
enum mismatch { enum mismatch {
TEXT_TO_ANY_INIT, TEXT_TO_ANY_INIT,
...@@ -1136,6 +1140,17 @@ static const struct sectioncheck *section_mismatch( ...@@ -1136,6 +1140,17 @@ static const struct sectioncheck *section_mismatch(
* This pattern is identified by * This pattern is identified by
* refsymname = __init_begin, _sinittext, _einittext * 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, static int secref_whitelist(const struct sectioncheck *mismatch,
const char *fromsec, const char *fromsym, const char *fromsec, const char *fromsym,
...@@ -1168,6 +1183,12 @@ static int secref_whitelist(const struct sectioncheck *mismatch, ...@@ -1168,6 +1183,12 @@ static int secref_whitelist(const struct sectioncheck *mismatch,
if (match(tosym, linker_symbols)) if (match(tosym, linker_symbols))
return 0; return 0;
/* Check for pattern 5 */
if (match(fromsec, text_sections) &&
match(tosec, init_sections) &&
match(fromsym, optim_symbols))
return 0;
return 1; return 1;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment