diff options
Diffstat (limited to 'scripts/mod/modpost.c')
-rw-r--r-- | scripts/mod/modpost.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index bd8349759095..4dedd0d3d3a7 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -609,6 +609,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info, { unsigned int crc; enum export export; + bool is_crc = false; if ((!is_vmlinux(mod->name) || mod->is_dot_o) && strncmp(symname, "__ksymtab", 9) == 0) @@ -618,7 +619,18 @@ static void handle_modversions(struct module *mod, struct elf_info *info, /* CRC'd symbol */ if (strncmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { + is_crc = true; crc = (unsigned int) sym->st_value; + if (sym->st_shndx != SHN_UNDEF && sym->st_shndx != SHN_ABS) { + unsigned int *crcp; + + /* symbol points to the CRC in the ELF object */ + crcp = (void *)info->hdr + sym->st_value + + info->sechdrs[sym->st_shndx].sh_offset - + (info->hdr->e_type != ET_REL ? + info->sechdrs[sym->st_shndx].sh_addr : 0); + crc = *crcp; + } sym_update_crc(symname + strlen(CRC_PFX), mod, crc, export); } @@ -663,6 +675,10 @@ static void handle_modversions(struct module *mod, struct elf_info *info, else symname++; #endif + if (is_crc) { + const char *e = is_vmlinux(mod->name) ?"":".ko"; + warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n", symname + strlen(CRC_PFX), mod->name, e); + } mod->unres = alloc_symbol(symname, ELF_ST_BIND(sym->st_info) == STB_WEAK, mod->unres); @@ -2371,6 +2387,7 @@ static void write_dump(const char *fname) } } write_if_changed(&buf, fname); + free(buf.p); } struct ext_sym_list { @@ -2496,6 +2513,7 @@ int main(int argc, char **argv) "Set CONFIG_SECTION_MISMATCH_WARN_ONLY=y to allow them.\n"); } } + free(buf.p); return err; } |