Commit 62a26356 authored by Alessio Igor Bogani's avatar Alessio Igor Bogani Committed by Rusty Russell

modpost: Fix modpost's license checking V3

The commit f02e8a65 sorts symbols placing each of them in its own elf section.
The sorting and merging into the canonical sections are done by the linker.
Unfortunately modpost to generate Module.symvers file parses vmlinux
(already linked) and all modules object files (which aren't linked yet).
These aren't sanitized by the linker yet. That breaks modpost that can't
detect license properly for modules. This patch makes modpost aware of
the new exported symbols structure.

Thanks to Arnaud Lacombe <lacombar@gmail.com> and Anders Kaseorg
<andersk@ksplice.com> for providing useful suggestions about code.

This work was supported by a hardware donation from the CE Linux Forum.
Reported-by: default avatarJan Beulich <jbeulich@novell.com>
Signed-off-by: default avatarAlessio Igor Bogani <abogani@kernel.org>
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent 88bfa324
...@@ -254,6 +254,28 @@ static enum export export_no(const char *s) ...@@ -254,6 +254,28 @@ static enum export export_no(const char *s)
return export_unknown; return export_unknown;
} }
static const char *sec_name(struct elf_info *elf, int secindex);
#define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0)
static enum export export_from_secname(struct elf_info *elf, unsigned int sec)
{
const char *secname = sec_name(elf, sec);
if (strstarts(secname, "___ksymtab+"))
return export_plain;
else if (strstarts(secname, "___ksymtab_unused+"))
return export_unused;
else if (strstarts(secname, "___ksymtab_gpl+"))
return export_gpl;
else if (strstarts(secname, "___ksymtab_unused_gpl+"))
return export_unused_gpl;
else if (strstarts(secname, "___ksymtab_gpl_future+"))
return export_gpl_future;
else
return export_unknown;
}
static enum export export_from_sec(struct elf_info *elf, unsigned int sec) static enum export export_from_sec(struct elf_info *elf, unsigned int sec)
{ {
if (sec == elf->export_sec) if (sec == elf->export_sec)
...@@ -563,7 +585,12 @@ static void handle_modversions(struct module *mod, struct elf_info *info, ...@@ -563,7 +585,12 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
Elf_Sym *sym, const char *symname) Elf_Sym *sym, const char *symname)
{ {
unsigned int crc; unsigned int crc;
enum export export = export_from_sec(info, get_secindex(info, sym)); enum export export;
if (!is_vmlinux(mod->name) && strncmp(symname, "__ksymtab", 9) == 0)
export = export_from_secname(info, get_secindex(info, sym));
else
export = export_from_sec(info, get_secindex(info, sym));
switch (sym->st_shndx) { switch (sym->st_shndx) {
case SHN_COMMON: case SHN_COMMON:
......
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