diff options
author | Andreas Robinson <andr345@gmail.com> | 2009-05-15 15:56:02 +0200 |
---|---|---|
committer | Andreas Robinson <andr345@gmail.com> | 2009-05-15 15:56:02 +0200 |
commit | a85e4c165f45767f09536f5baf9fe80ffedcc25a (patch) | |
tree | fd7798dd42e2fa0f470646dc6615d3a84355aa2f | |
parent | 45ec2644e6970f28fbf2acc789391de3e649f154 (diff) | |
download | module-init-tools-a85e4c165f45767f09536f5baf9fe80ffedcc25a.tar.gz |
modprobe, elfops: move most of dump_modversions() to elfops
Signed-off-by: Andreas Robinson <andr345@gmail.com>
-rw-r--r-- | elfops.c | 9 | ||||
-rw-r--r-- | elfops.h | 14 | ||||
-rw-r--r-- | elfops_core.c | 25 | ||||
-rw-r--r-- | modprobe.c | 55 |
4 files changed, 50 insertions, 53 deletions
@@ -19,6 +19,15 @@ static const char *weak_sym = "W"; static const char *undef_sym = "U"; +/* dump_modversions helper */ +static const char *skip_dot(const char *str) +{ + /* For our purposes, .foo matches foo. PPC64 needs this. */ + if (str && str[0] == '.') + return str + 1; + return str; +} + #define ELF32BIT #include "elfops_core.c" #undef ELF32BIT @@ -1,6 +1,7 @@ #ifndef MODINITTOOLS_MODULEOPS_H #define MODINITTOOLS_MODULEOPS_H #include <stdio.h> +#include <stdint.h> /* All the icky stuff to do with manipulating 64 and 32-bit modules belongs here. */ @@ -14,6 +15,18 @@ struct kernel_symbol64 { char name[64 - 8]; }; +struct modver_info32 +{ + uint32_t crc; + char name[64 - sizeof(uint32_t)]; +}; + +struct modver_info64 +{ + uint64_t crc; + char name[64 - sizeof(uint64_t)]; +}; + struct elf_file { char *pathname; @@ -66,6 +79,7 @@ struct module_ops char *(*get_aliases)(struct elf_file *module, unsigned long *size); char *(*get_modinfo)(struct elf_file *module, unsigned long *size); void (*strip_section)(struct elf_file *module, const char *secname); + int (*dump_modvers)(struct elf_file *module); }; extern struct module_ops mod_ops32, mod_ops64; diff --git a/elfops_core.c b/elfops_core.c index 14eef96..39fd4c3 100644 --- a/elfops_core.c +++ b/elfops_core.c @@ -318,6 +318,30 @@ static void PERBIT(strip_section)(struct elf_file *module, const char *secname) } } +static int PERBIT(dump_modversions)(struct elf_file *module) +{ + unsigned long secsize; + struct PERBIT(modver_info) *info; + int n = 0; + + info = module->ops->load_section(module, "__versions", &secsize); + if (!info) + return 0; /* not a kernel module */ + if (secsize % sizeof(*info) != 0) + return -1; /* invalid section size */ + + for (n = 0; n < secsize / sizeof(*info); n++) { +#if defined(ELF32BIT) + printf("0x%08lx\t%s\n", (unsigned long) +#else /* defined(ELF64BIT) */ + printf("0x%08llx\t%s\n", (unsigned long long) +#endif + END(info[n].crc, module->conv), + skip_dot(info[n].name)); + } + return n; +} + struct module_ops PERBIT(mod_ops) = { .load_section = PERBIT(load_section), .load_symbols = PERBIT(load_symbols), @@ -326,6 +350,7 @@ struct module_ops PERBIT(mod_ops) = { .get_aliases = PERBIT(get_aliases), .get_modinfo = PERBIT(get_modinfo), .strip_section = PERBIT(strip_section), + .dump_modvers = PERBIT(dump_modversions), }; #undef PERBIT @@ -792,71 +792,20 @@ nonexistent_module: goto remove_rest; } -struct modver32_info -{ - uint32_t crc; - char name[64 - sizeof(uint32_t)]; -}; - -struct modver64_info -{ - uint64_t crc; - char name[64 - sizeof(uint64_t)]; -}; - -const char *skip_dot(const char *str) -{ - /* For our purposes, .foo matches foo. PPC64 needs this. */ - if (str && str[0] == '.') - return str + 1; - return str; -} - void dump_modversions(const char *filename, errfn_t error) { struct elf_file *module; - unsigned long secsize; - void *info; - struct modver32_info *info32; - struct modver64_info *info64; - int n; module = grab_elf_file(filename); if (!module) { error("%s: %s\n", filename, strerror(errno)); return; } - info = module->ops->load_section(module, "__versions", &secsize); - if (!info) - goto done; /* Does not seem to be a kernel module */ - - switch (elf_ident(module->data, module->len, NULL)) { - case ELFCLASS32: - info32 = info; - if (secsize % sizeof(struct modver32_info)) - error("Wrong section size in %s\n", filename); - for (n = 0; n < secsize / sizeof(struct modver32_info); n++) - printf("0x%08lx\t%s\n", (unsigned long) - info32[n].crc, skip_dot(info32[n].name)); - break; - - case ELFCLASS64: - info64 = info; - if (secsize % sizeof(struct modver64_info)) - error("Wrong section size in %s\n", filename); - for (n = 0; n < secsize / sizeof(struct modver64_info); n++) - printf("0x%08llx\t%s\n", (unsigned long long) - info64[n].crc, skip_dot(info64[n].name)); - break; - - default: - error("%s: ELF class not recognized\n", filename); - } -done: + if (module->ops->dump_modvers(module) < 0) + error("Wrong section size in '%s'\n", filename); release_elf_file(module); } - /* Does path contain directory(s) subpath? */ static int type_matches(const char *path, const char *subpath) { |