aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/mod
diff options
context:
space:
mode:
authorAlessio Igor Bogani <abogani@kernel.org>2011-07-14 02:51:16 -0400
committerRusty Russell <rusty@rustcorp.com.au>2011-07-24 08:36:05 -0400
commit62a2635610dbc83c5e8d724e00941eee4d18c186 (patch)
tree57fe7dbb569e3b69a1b2adbba1c14e9959ed64d1 /scripts/mod
parent88bfa3247961fe5f3623f4d2cf1cd5dc72457598 (diff)
modpost: Fix modpost's license checking V3
The commit f02e8a6 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: Jan Beulich <jbeulich@novell.com> Signed-off-by: Alessio Igor Bogani <abogani@kernel.org> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'scripts/mod')
-rw-r--r--scripts/mod/modpost.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 413c53693e62..a509ff8f32fa 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -254,6 +254,28 @@ static enum export export_no(const char *s)
254 return export_unknown; 254 return export_unknown;
255} 255}
256 256
257static const char *sec_name(struct elf_info *elf, int secindex);
258
259#define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0)
260
261static enum export export_from_secname(struct elf_info *elf, unsigned int sec)
262{
263 const char *secname = sec_name(elf, sec);
264
265 if (strstarts(secname, "___ksymtab+"))
266 return export_plain;
267 else if (strstarts(secname, "___ksymtab_unused+"))
268 return export_unused;
269 else if (strstarts(secname, "___ksymtab_gpl+"))
270 return export_gpl;
271 else if (strstarts(secname, "___ksymtab_unused_gpl+"))
272 return export_unused_gpl;
273 else if (strstarts(secname, "___ksymtab_gpl_future+"))
274 return export_gpl_future;
275 else
276 return export_unknown;
277}
278
257static enum export export_from_sec(struct elf_info *elf, unsigned int sec) 279static enum export export_from_sec(struct elf_info *elf, unsigned int sec)
258{ 280{
259 if (sec == elf->export_sec) 281 if (sec == elf->export_sec)
@@ -563,7 +585,12 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
563 Elf_Sym *sym, const char *symname) 585 Elf_Sym *sym, const char *symname)
564{ 586{
565 unsigned int crc; 587 unsigned int crc;
566 enum export export = export_from_sec(info, get_secindex(info, sym)); 588 enum export export;
589
590 if (!is_vmlinux(mod->name) && strncmp(symname, "__ksymtab", 9) == 0)
591 export = export_from_secname(info, get_secindex(info, sym));
592 else
593 export = export_from_sec(info, get_secindex(info, sym));
567 594
568 switch (sym->st_shndx) { 595 switch (sym->st_shndx) {
569 case SHN_COMMON: 596 case SHN_COMMON: