Commit 1087247b authored by Sam Ravnborg's avatar Sam Ravnborg

kbuild: refactor code in modpost to improve maintainability

There were a great deal of overlap between the two functions
that check which sections may reference .init.text and .exit.text.
Factor out common check to a separate function and
sort entries in the original functions.
Signed-off-by: default avatarSam Ravnborg <sam@ravnborg.org>
parent b28242e7
...@@ -858,14 +858,6 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec, ...@@ -858,14 +858,6 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec,
elf->strtab + before->st_name, refsymname)) elf->strtab + before->st_name, refsymname))
return; return;
/* fromsec whitelist - without a valid 'before'
* powerpc has a GOT table in .got2 section
* and also a .toc section */
if (strcmp(fromsec, ".got2") == 0)
return;
if (strcmp(fromsec, ".toc") == 0)
return;
if (before && after) { if (before && after) {
warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s " warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s "
"(between '%s' and '%s')\n", "(between '%s' and '%s')\n",
...@@ -1087,6 +1079,61 @@ static void check_sec_ref(struct module *mod, const char *modname, ...@@ -1087,6 +1079,61 @@ static void check_sec_ref(struct module *mod, const char *modname,
} }
} }
/*
* Identify sections from which references to either a
* .init or a .exit section is OK.
*
* [OPD] Keith Ownes <kaos@sgi.com> commented:
* For our future {in}sanity, add a comment that this is the ppc .opd
* section, not the ia64 .opd section.
* ia64 .opd should not point to discarded sections.
* [.rodata] like for .init.text we ignore .rodata references -same reason
**/
static int initexit_section_ref_ok(const char *name)
{
const char **s;
/* Absolute section names */
const char *namelist1[] = {
"__bug_table", /* used by powerpc for BUG() */
"__ex_table",
".altinstructions",
".cranges", /* used by sh64 */
".fixup",
".opd", /* See comment [OPD] */
".parainstructions",
".pdr",
".plt", /* seen on ARCH=um build on x86_64. Harmless */
".smp_locks",
".stab",
NULL
};
/* Start of section names */
const char *namelist2[] = {
".debug",
".eh_frame",
".note", /* ignore ELF notes - may contain anything */
".got", /* powerpc - global offset table */
".toc", /* powerpc - table of contents */
NULL
};
/* part of section name */
const char *namelist3 [] = {
".unwind", /* Sample: IA_64.unwind.exit.text */
NULL
};
for (s = namelist1; *s; s++)
if (strcmp(*s, name) == 0)
return 1;
for (s = namelist2; *s; s++)
if (strncmp(*s, name, strlen(*s)) == 0)
return 1;
for (s = namelist3; *s; s++)
if (strstr(name, *s) != NULL)
return 1;
return 0;
}
/** /**
* Functions used only during module init is marked __init and is stored in * Functions used only during module init is marked __init and is stored in
* a .init.text section. Likewise data is marked __initdata and stored in * a .init.text section. Likewise data is marked __initdata and stored in
...@@ -1103,7 +1150,7 @@ static int init_section(const char *name) ...@@ -1103,7 +1150,7 @@ static int init_section(const char *name)
return 0; return 0;
} }
/** /*
* Identify sections from which references to a .init section is OK. * Identify sections from which references to a .init section is OK.
* *
* Unfortunately references to read only data that referenced .init * Unfortunately references to read only data that referenced .init
...@@ -1117,59 +1164,41 @@ static int init_section(const char *name) ...@@ -1117,59 +1164,41 @@ static int init_section(const char *name)
* *
* where vgacon_startup is __init. If you want to wade through the false * where vgacon_startup is __init. If you want to wade through the false
* positives, take out the check for rodata. * positives, take out the check for rodata.
**/ */
static int init_section_ref_ok(const char *name) static int init_section_ref_ok(const char *name)
{ {
const char **s; const char **s;
/* Absolute section names */ /* Absolute section names */
const char *namelist1[] = { const char *namelist1[] = {
".init",
".opd", /* see comment [OPD] at exit_section_ref_ok() */
".toc1", /* used by ppc64 */
".stab",
".data.rel.ro", /* used by parisc64 */
".parainstructions",
".text.lock",
"__bug_table", /* used by powerpc for BUG() */
".pci_fixup_header",
".pci_fixup_final",
".pdr",
"__param",
"__ex_table",
".fixup",
".smp_locks",
".plt", /* seen on ARCH=um build on x86_64. Harmless */
"__ftr_fixup", /* powerpc cpu feature fixup */ "__ftr_fixup", /* powerpc cpu feature fixup */
"__fw_ftr_fixup", /* powerpc firmware feature fixup */ "__fw_ftr_fixup", /* powerpc firmware feature fixup */
".cranges", /* used by sh64 */ "__param",
".data.rel.ro", /* used by parisc64 */
".init",
".text.lock",
NULL NULL
}; };
/* Start of section names */ /* Start of section names */
const char *namelist2[] = { const char *namelist2[] = {
".init.", ".init.",
".altinstructions", ".pci_fixup",
".eh_frame",
".debug",
".parainstructions",
".rodata", ".rodata",
".note", /* ignore ELF notes - may contain anything */
NULL
};
/* part of section name */
const char *namelist3 [] = {
".unwind", /* sample: IA_64.unwind.init.text */
NULL NULL
}; };
if (initexit_section_ref_ok(name))
return 1;
for (s = namelist1; *s; s++) for (s = namelist1; *s; s++)
if (strcmp(*s, name) == 0) if (strcmp(*s, name) == 0)
return 1; return 1;
for (s = namelist2; *s; s++) for (s = namelist2; *s; s++)
if (strncmp(*s, name, strlen(*s)) == 0) if (strncmp(*s, name, strlen(*s)) == 0)
return 1; return 1;
for (s = namelist3; *s; s++)
if (strstr(name, *s) != NULL) /* If section name ends with ".init" we allow references
return 1; * as is the case with .initcallN.init, .early_param.init, .taglist.init etc
*/
if (strrcmp(name, ".init") == 0) if (strrcmp(name, ".init") == 0)
return 1; return 1;
return 0; return 0;
...@@ -1194,59 +1223,26 @@ static int exit_section(const char *name) ...@@ -1194,59 +1223,26 @@ static int exit_section(const char *name)
/* /*
* Identify sections from which references to a .exit section is OK. * Identify sections from which references to a .exit section is OK.
* */
* [OPD] Keith Ownes <kaos@sgi.com> commented:
* For our future {in}sanity, add a comment that this is the ppc .opd
* section, not the ia64 .opd section.
* ia64 .opd should not point to discarded sections.
* [.rodata] like for .init.text we ignore .rodata references -same reason
**/
static int exit_section_ref_ok(const char *name) static int exit_section_ref_ok(const char *name)
{ {
const char **s; const char **s;
/* Absolute section names */ /* Absolute section names */
const char *namelist1[] = { const char *namelist1[] = {
".exit.text",
".exit.data", ".exit.data",
".exit.text",
".exitcall.exit",
".init.text", ".init.text",
".rodata", ".rodata",
".opd", /* See comment [OPD] */
".toc1", /* used by ppc64 */
".altinstructions",
".pdr",
"__bug_table", /* used by powerpc for BUG() */
".exitcall.exit",
".eh_frame",
".parainstructions",
".stab",
"__ex_table",
".fixup",
".smp_locks",
".plt", /* seen on ARCH=um build on x86_64. Harmless */
".cranges", /* used by sh64 */
NULL
};
/* Start of section names */
const char *namelist2[] = {
".debug",
".note", /* ignore ELF notes - may contain anything */
NULL
};
/* part of section name */
const char *namelist3 [] = {
".unwind", /* Sample: IA_64.unwind.exit.text */
NULL NULL
}; };
if (initexit_section_ref_ok(name))
return 1;
for (s = namelist1; *s; s++) for (s = namelist1; *s; s++)
if (strcmp(*s, name) == 0) if (strcmp(*s, name) == 0)
return 1; return 1;
for (s = namelist2; *s; s++)
if (strncmp(*s, name, strlen(*s)) == 0)
return 1;
for (s = namelist3; *s; s++)
if (strstr(name, *s) != NULL)
return 1;
return 0; return 0;
} }
......
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