Commit 2cb54ce9 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'modversions' (modversions fixes for powerpc from Ard)

Merge kcrctab entry fixes from Ard Biesheuvel:
 "This is a followup to [0] 'modversions: redefine kcrctab entries as
  relative CRC pointers', but since relative CRC pointers do not work in
  modules, and are actually only needed by powerpc with
  CONFIG_RELOCATABLE=y, I have made it a Kconfig selectable feature
  instead.

  First it introduces the MODULE_REL_CRCS Kconfig symbol, and adds the
  kbuild handling of it, i.e., modpost, genksyms and kallsyms.

  Then it switches all architectures to 32-bit CRC entries in kcrctab,
  where all architectures except powerpc with CONFIG_RELOCATABLE=y use
  absolute ELF symbol references as before"

[0] http://marc.info/?l=linux-arch&m=148493613415294&w=2

* emailed patches from Ard Biesheuvel:
  module: unify absolute krctab definitions for 32-bit and 64-bit
  modversions: treat symbol CRCs as 32 bit quantities
  kbuild: modversions: add infrastructure for emitting relative CRCs
parents 29905b52 4b9eee96
...@@ -484,6 +484,7 @@ config RELOCATABLE ...@@ -484,6 +484,7 @@ config RELOCATABLE
bool "Build a relocatable kernel" bool "Build a relocatable kernel"
depends on (PPC64 && !COMPILE_TEST) || (FLATMEM && (44x || FSL_BOOKE)) depends on (PPC64 && !COMPILE_TEST) || (FLATMEM && (44x || FSL_BOOKE))
select NONSTATIC_KERNEL select NONSTATIC_KERNEL
select MODULE_REL_CRCS if MODVERSIONS
help help
This builds a kernel image that is capable of running at the This builds a kernel image that is capable of running at the
location the kernel is loaded at. For ppc32, there is no any location the kernel is loaded at. For ppc32, there is no any
......
...@@ -90,9 +90,5 @@ static inline int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sec ...@@ -90,9 +90,5 @@ static inline int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sec
} }
#endif #endif
#if defined(CONFIG_MODVERSIONS) && defined(CONFIG_PPC64)
#define ARCH_RELOCATES_KCRCTAB
#define reloc_start PHYSICAL_START
#endif
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_MODULE_H */ #endif /* _ASM_POWERPC_MODULE_H */
...@@ -286,14 +286,6 @@ static void dedotify_versions(struct modversion_info *vers, ...@@ -286,14 +286,6 @@ static void dedotify_versions(struct modversion_info *vers,
for (end = (void *)vers + size; vers < end; vers++) for (end = (void *)vers + size; vers < end; vers++)
if (vers->name[0] == '.') { if (vers->name[0] == '.') {
memmove(vers->name, vers->name+1, strlen(vers->name)); memmove(vers->name, vers->name+1, strlen(vers->name));
#ifdef ARCH_RELOCATES_KCRCTAB
/* The TOC symbol has no CRC computed. To avoid CRC
* check failing, we must force it to the expected
* value (see CRC check in module.c).
*/
if (!strcmp(vers->name, "TOC."))
vers->crc = -(unsigned long)reloc_start;
#endif
} }
} }
......
...@@ -9,18 +9,15 @@ ...@@ -9,18 +9,15 @@
#ifndef KSYM_ALIGN #ifndef KSYM_ALIGN
#define KSYM_ALIGN 8 #define KSYM_ALIGN 8
#endif #endif
#ifndef KCRC_ALIGN
#define KCRC_ALIGN 8
#endif
#else #else
#define __put .long #define __put .long
#ifndef KSYM_ALIGN #ifndef KSYM_ALIGN
#define KSYM_ALIGN 4 #define KSYM_ALIGN 4
#endif #endif
#endif
#ifndef KCRC_ALIGN #ifndef KCRC_ALIGN
#define KCRC_ALIGN 4 #define KCRC_ALIGN 4
#endif #endif
#endif
#ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX #ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX
#define KSYM(name) _##name #define KSYM(name) _##name
...@@ -52,7 +49,11 @@ KSYM(__kstrtab_\name): ...@@ -52,7 +49,11 @@ KSYM(__kstrtab_\name):
.section ___kcrctab\sec+\name,"a" .section ___kcrctab\sec+\name,"a"
.balign KCRC_ALIGN .balign KCRC_ALIGN
KSYM(__kcrctab_\name): KSYM(__kcrctab_\name):
__put KSYM(__crc_\name) #if defined(CONFIG_MODULE_REL_CRCS)
.long KSYM(__crc_\name) - .
#else
.long KSYM(__crc_\name)
#endif
.weak KSYM(__crc_\name) .weak KSYM(__crc_\name)
.previous .previous
#endif #endif
......
...@@ -43,12 +43,19 @@ extern struct module __this_module; ...@@ -43,12 +43,19 @@ extern struct module __this_module;
#ifdef CONFIG_MODVERSIONS #ifdef CONFIG_MODVERSIONS
/* Mark the CRC weak since genksyms apparently decides not to /* Mark the CRC weak since genksyms apparently decides not to
* generate a checksums for some symbols */ * generate a checksums for some symbols */
#if defined(CONFIG_MODULE_REL_CRCS)
#define __CRC_SYMBOL(sym, sec) \ #define __CRC_SYMBOL(sym, sec) \
extern __visible void *__crc_##sym __attribute__((weak)); \ asm(" .section \"___kcrctab" sec "+" #sym "\", \"a\" \n" \
static const unsigned long __kcrctab_##sym \ " .weak " VMLINUX_SYMBOL_STR(__crc_##sym) " \n" \
__used \ " .long " VMLINUX_SYMBOL_STR(__crc_##sym) " - . \n" \
__attribute__((section("___kcrctab" sec "+" #sym), used)) \ " .previous \n");
= (unsigned long) &__crc_##sym; #else
#define __CRC_SYMBOL(sym, sec) \
asm(" .section \"___kcrctab" sec "+" #sym "\", \"a\" \n" \
" .weak " VMLINUX_SYMBOL_STR(__crc_##sym) " \n" \
" .long " VMLINUX_SYMBOL_STR(__crc_##sym) " \n" \
" .previous \n");
#endif
#else #else
#define __CRC_SYMBOL(sym, sec) #define __CRC_SYMBOL(sym, sec)
#endif #endif
......
...@@ -346,7 +346,7 @@ struct module { ...@@ -346,7 +346,7 @@ struct module {
/* Exported symbols */ /* Exported symbols */
const struct kernel_symbol *syms; const struct kernel_symbol *syms;
const unsigned long *crcs; const s32 *crcs;
unsigned int num_syms; unsigned int num_syms;
/* Kernel parameters. */ /* Kernel parameters. */
...@@ -359,18 +359,18 @@ struct module { ...@@ -359,18 +359,18 @@ struct module {
/* GPL-only exported symbols. */ /* GPL-only exported symbols. */
unsigned int num_gpl_syms; unsigned int num_gpl_syms;
const struct kernel_symbol *gpl_syms; const struct kernel_symbol *gpl_syms;
const unsigned long *gpl_crcs; const s32 *gpl_crcs;
#ifdef CONFIG_UNUSED_SYMBOLS #ifdef CONFIG_UNUSED_SYMBOLS
/* unused exported symbols. */ /* unused exported symbols. */
const struct kernel_symbol *unused_syms; const struct kernel_symbol *unused_syms;
const unsigned long *unused_crcs; const s32 *unused_crcs;
unsigned int num_unused_syms; unsigned int num_unused_syms;
/* GPL-only, unused exported symbols. */ /* GPL-only, unused exported symbols. */
unsigned int num_unused_gpl_syms; unsigned int num_unused_gpl_syms;
const struct kernel_symbol *unused_gpl_syms; const struct kernel_symbol *unused_gpl_syms;
const unsigned long *unused_gpl_crcs; const s32 *unused_gpl_crcs;
#endif #endif
#ifdef CONFIG_MODULE_SIG #ifdef CONFIG_MODULE_SIG
...@@ -382,7 +382,7 @@ struct module { ...@@ -382,7 +382,7 @@ struct module {
/* symbols that will be GPL-only in the near future. */ /* symbols that will be GPL-only in the near future. */
const struct kernel_symbol *gpl_future_syms; const struct kernel_symbol *gpl_future_syms;
const unsigned long *gpl_future_crcs; const s32 *gpl_future_crcs;
unsigned int num_gpl_future_syms; unsigned int num_gpl_future_syms;
/* Exception table */ /* Exception table */
...@@ -523,7 +523,7 @@ struct module *find_module(const char *name); ...@@ -523,7 +523,7 @@ struct module *find_module(const char *name);
struct symsearch { struct symsearch {
const struct kernel_symbol *start, *stop; const struct kernel_symbol *start, *stop;
const unsigned long *crcs; const s32 *crcs;
enum { enum {
NOT_GPL_ONLY, NOT_GPL_ONLY,
GPL_ONLY, GPL_ONLY,
...@@ -539,7 +539,7 @@ struct symsearch { ...@@ -539,7 +539,7 @@ struct symsearch {
*/ */
const struct kernel_symbol *find_symbol(const char *name, const struct kernel_symbol *find_symbol(const char *name,
struct module **owner, struct module **owner,
const unsigned long **crc, const s32 **crc,
bool gplok, bool gplok,
bool warn); bool warn);
......
...@@ -1987,6 +1987,10 @@ config MODVERSIONS ...@@ -1987,6 +1987,10 @@ config MODVERSIONS
make them incompatible with the kernel you are running. If make them incompatible with the kernel you are running. If
unsure, say N. unsure, say N.
config MODULE_REL_CRCS
bool
depends on MODVERSIONS
config MODULE_SRCVERSION_ALL config MODULE_SRCVERSION_ALL
bool "Source checksum for all modules" bool "Source checksum for all modules"
help help
......
...@@ -389,16 +389,16 @@ extern const struct kernel_symbol __start___ksymtab_gpl[]; ...@@ -389,16 +389,16 @@ extern const struct kernel_symbol __start___ksymtab_gpl[];
extern const struct kernel_symbol __stop___ksymtab_gpl[]; extern const struct kernel_symbol __stop___ksymtab_gpl[];
extern const struct kernel_symbol __start___ksymtab_gpl_future[]; extern const struct kernel_symbol __start___ksymtab_gpl_future[];
extern const struct kernel_symbol __stop___ksymtab_gpl_future[]; extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
extern const unsigned long __start___kcrctab[]; extern const s32 __start___kcrctab[];
extern const unsigned long __start___kcrctab_gpl[]; extern const s32 __start___kcrctab_gpl[];
extern const unsigned long __start___kcrctab_gpl_future[]; extern const s32 __start___kcrctab_gpl_future[];
#ifdef CONFIG_UNUSED_SYMBOLS #ifdef CONFIG_UNUSED_SYMBOLS
extern const struct kernel_symbol __start___ksymtab_unused[]; extern const struct kernel_symbol __start___ksymtab_unused[];
extern const struct kernel_symbol __stop___ksymtab_unused[]; extern const struct kernel_symbol __stop___ksymtab_unused[];
extern const struct kernel_symbol __start___ksymtab_unused_gpl[]; extern const struct kernel_symbol __start___ksymtab_unused_gpl[];
extern const struct kernel_symbol __stop___ksymtab_unused_gpl[]; extern const struct kernel_symbol __stop___ksymtab_unused_gpl[];
extern const unsigned long __start___kcrctab_unused[]; extern const s32 __start___kcrctab_unused[];
extern const unsigned long __start___kcrctab_unused_gpl[]; extern const s32 __start___kcrctab_unused_gpl[];
#endif #endif
#ifndef CONFIG_MODVERSIONS #ifndef CONFIG_MODVERSIONS
...@@ -497,7 +497,7 @@ struct find_symbol_arg { ...@@ -497,7 +497,7 @@ struct find_symbol_arg {
/* Output */ /* Output */
struct module *owner; struct module *owner;
const unsigned long *crc; const s32 *crc;
const struct kernel_symbol *sym; const struct kernel_symbol *sym;
}; };
...@@ -563,7 +563,7 @@ static bool find_symbol_in_section(const struct symsearch *syms, ...@@ -563,7 +563,7 @@ static bool find_symbol_in_section(const struct symsearch *syms,
* (optional) module which owns it. Needs preempt disabled or module_mutex. */ * (optional) module which owns it. Needs preempt disabled or module_mutex. */
const struct kernel_symbol *find_symbol(const char *name, const struct kernel_symbol *find_symbol(const char *name,
struct module **owner, struct module **owner,
const unsigned long **crc, const s32 **crc,
bool gplok, bool gplok,
bool warn) bool warn)
{ {
...@@ -1249,23 +1249,17 @@ static int try_to_force_load(struct module *mod, const char *reason) ...@@ -1249,23 +1249,17 @@ static int try_to_force_load(struct module *mod, const char *reason)
} }
#ifdef CONFIG_MODVERSIONS #ifdef CONFIG_MODVERSIONS
/* If the arch applies (non-zero) relocations to kernel kcrctab, unapply it. */
static unsigned long maybe_relocated(unsigned long crc, static u32 resolve_rel_crc(const s32 *crc)
const struct module *crc_owner)
{ {
#ifdef ARCH_RELOCATES_KCRCTAB return *(u32 *)((void *)crc + *crc);
if (crc_owner == NULL)
return crc - (unsigned long)reloc_start;
#endif
return crc;
} }
static int check_version(Elf_Shdr *sechdrs, static int check_version(Elf_Shdr *sechdrs,
unsigned int versindex, unsigned int versindex,
const char *symname, const char *symname,
struct module *mod, struct module *mod,
const unsigned long *crc, const s32 *crc)
const struct module *crc_owner)
{ {
unsigned int i, num_versions; unsigned int i, num_versions;
struct modversion_info *versions; struct modversion_info *versions;
...@@ -1283,13 +1277,19 @@ static int check_version(Elf_Shdr *sechdrs, ...@@ -1283,13 +1277,19 @@ static int check_version(Elf_Shdr *sechdrs,
/ sizeof(struct modversion_info); / sizeof(struct modversion_info);
for (i = 0; i < num_versions; i++) { for (i = 0; i < num_versions; i++) {
u32 crcval;
if (strcmp(versions[i].name, symname) != 0) if (strcmp(versions[i].name, symname) != 0)
continue; continue;
if (versions[i].crc == maybe_relocated(*crc, crc_owner)) if (IS_ENABLED(CONFIG_MODULE_REL_CRCS))
crcval = resolve_rel_crc(crc);
else
crcval = *crc;
if (versions[i].crc == crcval)
return 1; return 1;
pr_debug("Found checksum %lX vs module %lX\n", pr_debug("Found checksum %X vs module %lX\n",
maybe_relocated(*crc, crc_owner), versions[i].crc); crcval, versions[i].crc);
goto bad_version; goto bad_version;
} }
...@@ -1307,7 +1307,7 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs, ...@@ -1307,7 +1307,7 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs,
unsigned int versindex, unsigned int versindex,
struct module *mod) struct module *mod)
{ {
const unsigned long *crc; const s32 *crc;
/* /*
* Since this should be found in kernel (which can't be removed), no * Since this should be found in kernel (which can't be removed), no
...@@ -1321,8 +1321,7 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs, ...@@ -1321,8 +1321,7 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs,
} }
preempt_enable(); preempt_enable();
return check_version(sechdrs, versindex, return check_version(sechdrs, versindex,
VMLINUX_SYMBOL_STR(module_layout), mod, crc, VMLINUX_SYMBOL_STR(module_layout), mod, crc);
NULL);
} }
/* First part is kernel version, which we ignore if module has crcs. */ /* First part is kernel version, which we ignore if module has crcs. */
...@@ -1340,8 +1339,7 @@ static inline int check_version(Elf_Shdr *sechdrs, ...@@ -1340,8 +1339,7 @@ static inline int check_version(Elf_Shdr *sechdrs,
unsigned int versindex, unsigned int versindex,
const char *symname, const char *symname,
struct module *mod, struct module *mod,
const unsigned long *crc, const s32 *crc)
const struct module *crc_owner)
{ {
return 1; return 1;
} }
...@@ -1368,7 +1366,7 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod, ...@@ -1368,7 +1366,7 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
{ {
struct module *owner; struct module *owner;
const struct kernel_symbol *sym; const struct kernel_symbol *sym;
const unsigned long *crc; const s32 *crc;
int err; int err;
/* /*
...@@ -1383,8 +1381,7 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod, ...@@ -1383,8 +1381,7 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
if (!sym) if (!sym)
goto unlock; goto unlock;
if (!check_version(info->sechdrs, info->index.vers, name, mod, crc, if (!check_version(info->sechdrs, info->index.vers, name, mod, crc)) {
owner)) {
sym = ERR_PTR(-EINVAL); sym = ERR_PTR(-EINVAL);
goto getname; goto getname;
} }
......
...@@ -164,6 +164,7 @@ cmd_gensymtypes_c = \ ...@@ -164,6 +164,7 @@ cmd_gensymtypes_c = \
$(CPP) -D__GENKSYMS__ $(c_flags) $< | \ $(CPP) -D__GENKSYMS__ $(c_flags) $< | \
$(GENKSYMS) $(if $(1), -T $(2)) \ $(GENKSYMS) $(if $(1), -T $(2)) \
$(patsubst y,-s _,$(CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX)) \ $(patsubst y,-s _,$(CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX)) \
$(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS)) \
$(if $(KBUILD_PRESERVE),-p) \ $(if $(KBUILD_PRESERVE),-p) \
-r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null)) -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
...@@ -337,6 +338,7 @@ cmd_gensymtypes_S = \ ...@@ -337,6 +338,7 @@ cmd_gensymtypes_S = \
$(CPP) -D__GENKSYMS__ $(c_flags) -xc - | \ $(CPP) -D__GENKSYMS__ $(c_flags) -xc - | \
$(GENKSYMS) $(if $(1), -T $(2)) \ $(GENKSYMS) $(if $(1), -T $(2)) \
$(patsubst y,-s _,$(CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX)) \ $(patsubst y,-s _,$(CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX)) \
$(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS)) \
$(if $(KBUILD_PRESERVE),-p) \ $(if $(KBUILD_PRESERVE),-p) \
-r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null)) -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
......
...@@ -44,7 +44,7 @@ char *cur_filename, *source_file; ...@@ -44,7 +44,7 @@ char *cur_filename, *source_file;
int in_source_file; int in_source_file;
static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types, static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types,
flag_preserve, flag_warnings; flag_preserve, flag_warnings, flag_rel_crcs;
static const char *mod_prefix = ""; static const char *mod_prefix = "";
static int errors; static int errors;
...@@ -693,7 +693,10 @@ void export_symbol(const char *name) ...@@ -693,7 +693,10 @@ void export_symbol(const char *name)
fputs(">\n", debugfile); fputs(">\n", debugfile);
/* Used as a linker script. */ /* Used as a linker script. */
printf("%s__crc_%s = 0x%08lx ;\n", mod_prefix, name, crc); printf(!flag_rel_crcs ? "%s__crc_%s = 0x%08lx;\n" :
"SECTIONS { .rodata : ALIGN(4) { "
"%s__crc_%s = .; LONG(0x%08lx); } }\n",
mod_prefix, name, crc);
} }
} }
...@@ -730,7 +733,7 @@ void error_with_pos(const char *fmt, ...) ...@@ -730,7 +733,7 @@ void error_with_pos(const char *fmt, ...)
static void genksyms_usage(void) static void genksyms_usage(void)
{ {
fputs("Usage:\n" "genksyms [-adDTwqhV] > /path/to/.tmp_obj.ver\n" "\n" fputs("Usage:\n" "genksyms [-adDTwqhVR] > /path/to/.tmp_obj.ver\n" "\n"
#ifdef __GNU_LIBRARY__ #ifdef __GNU_LIBRARY__
" -s, --symbol-prefix Select symbol prefix\n" " -s, --symbol-prefix Select symbol prefix\n"
" -d, --debug Increment the debug level (repeatable)\n" " -d, --debug Increment the debug level (repeatable)\n"
...@@ -742,6 +745,7 @@ static void genksyms_usage(void) ...@@ -742,6 +745,7 @@ static void genksyms_usage(void)
" -q, --quiet Disable warnings (default)\n" " -q, --quiet Disable warnings (default)\n"
" -h, --help Print this message\n" " -h, --help Print this message\n"
" -V, --version Print the release version\n" " -V, --version Print the release version\n"
" -R, --relative-crc Emit section relative symbol CRCs\n"
#else /* __GNU_LIBRARY__ */ #else /* __GNU_LIBRARY__ */
" -s Select symbol prefix\n" " -s Select symbol prefix\n"
" -d Increment the debug level (repeatable)\n" " -d Increment the debug level (repeatable)\n"
...@@ -753,6 +757,7 @@ static void genksyms_usage(void) ...@@ -753,6 +757,7 @@ static void genksyms_usage(void)
" -q Disable warnings (default)\n" " -q Disable warnings (default)\n"
" -h Print this message\n" " -h Print this message\n"
" -V Print the release version\n" " -V Print the release version\n"
" -R Emit section relative symbol CRCs\n"
#endif /* __GNU_LIBRARY__ */ #endif /* __GNU_LIBRARY__ */
, stderr); , stderr);
} }
...@@ -774,13 +779,14 @@ int main(int argc, char **argv) ...@@ -774,13 +779,14 @@ int main(int argc, char **argv)
{"preserve", 0, 0, 'p'}, {"preserve", 0, 0, 'p'},
{"version", 0, 0, 'V'}, {"version", 0, 0, 'V'},
{"help", 0, 0, 'h'}, {"help", 0, 0, 'h'},
{"relative-crc", 0, 0, 'R'},
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
while ((o = getopt_long(argc, argv, "s:dwqVDr:T:ph", while ((o = getopt_long(argc, argv, "s:dwqVDr:T:phR",
&long_opts[0], NULL)) != EOF) &long_opts[0], NULL)) != EOF)
#else /* __GNU_LIBRARY__ */ #else /* __GNU_LIBRARY__ */
while ((o = getopt(argc, argv, "s:dwqVDr:T:ph")) != EOF) while ((o = getopt(argc, argv, "s:dwqVDr:T:phR")) != EOF)
#endif /* __GNU_LIBRARY__ */ #endif /* __GNU_LIBRARY__ */
switch (o) { switch (o) {
case 's': case 's':
...@@ -823,6 +829,9 @@ int main(int argc, char **argv) ...@@ -823,6 +829,9 @@ int main(int argc, char **argv)
case 'h': case 'h':
genksyms_usage(); genksyms_usage();
return 0; return 0;
case 'R':
flag_rel_crcs = 1;
break;
default: default:
genksyms_usage(); genksyms_usage();
return 1; return 1;
......
...@@ -219,6 +219,10 @@ static int symbol_valid(struct sym_entry *s) ...@@ -219,6 +219,10 @@ static int symbol_valid(struct sym_entry *s)
"_SDA2_BASE_", /* ppc */ "_SDA2_BASE_", /* ppc */
NULL }; NULL };
static char *special_prefixes[] = {
"__crc_", /* modversions */
NULL };
static char *special_suffixes[] = { static char *special_suffixes[] = {
"_veneer", /* arm */ "_veneer", /* arm */
"_from_arm", /* arm */ "_from_arm", /* arm */
...@@ -259,6 +263,14 @@ static int symbol_valid(struct sym_entry *s) ...@@ -259,6 +263,14 @@ static int symbol_valid(struct sym_entry *s)
if (strcmp(sym_name, special_symbols[i]) == 0) if (strcmp(sym_name, special_symbols[i]) == 0)
return 0; return 0;
for (i = 0; special_prefixes[i]; i++) {
int l = strlen(special_prefixes[i]);
if (l <= strlen(sym_name) &&
strncmp(sym_name, special_prefixes[i], l) == 0)
return 0;
}
for (i = 0; special_suffixes[i]; i++) { for (i = 0; special_suffixes[i]; i++) {
int l = strlen(sym_name) - strlen(special_suffixes[i]); int l = strlen(sym_name) - strlen(special_suffixes[i]);
......
...@@ -621,6 +621,16 @@ static void handle_modversions(struct module *mod, struct elf_info *info, ...@@ -621,6 +621,16 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
if (strncmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { if (strncmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
is_crc = true; is_crc = true;
crc = (unsigned int) sym->st_value; 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, sym_update_crc(symname + strlen(CRC_PFX), mod, crc,
export); export);
} }
......
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