diff options
author | Jon Masters <jcm@jonmasters.org> | 2009-05-27 12:49:59 -0400 |
---|---|---|
committer | Jon Masters <jcm@jonmasters.org> | 2009-05-27 12:49:59 -0400 |
commit | bd2f38809e831d8541f35121ad4ed560a0b7ef5e (patch) | |
tree | 2dc40b05b080332b5cd1316a83b5987ab064e090 | |
parent | 7046f4539b0eaceb6923981fd718a3c44d47a353 (diff) | |
parent | d1877dc6e4bbc5344990cc6df6a35cc45f246788 (diff) | |
download | module-init-tools-bd2f38809e831d8541f35121ad4ed560a0b7ef5e.tar.gz |
Merge branch 'elf_cleanup3' of ../module_init_tools_andr345
-rw-r--r-- | depmod.c | 44 | ||||
-rw-r--r-- | elfops.h | 3 | ||||
-rw-r--r-- | elfops_core.c | 26 | ||||
-rw-r--r-- | logging.h | 2 | ||||
-rw-r--r-- | modinfo.c | 25 | ||||
-rw-r--r-- | modprobe.c | 32 | ||||
-rw-r--r-- | tests/test-modprobe-indexed/10alias.sh | 9 | ||||
-rwxr-xr-x | tests/test-modprobe/10alias.sh | 9 | ||||
-rwxr-xr-x | tests/test-modprobe/26blacklist.sh | 7 | ||||
-rw-r--r-- | util.c | 2 | ||||
-rw-r--r-- | util.h | 1 |
11 files changed, 78 insertions, 82 deletions
@@ -693,7 +693,7 @@ static struct module *parse_modules(struct module *list) if (syms) { for (j = 0; j < syms->cnt; j++) add_symbol(syms->str[j], i); - free(syms); + strtbl_free(syms); } file->ops->fetch_tables(file, &i->tables); } @@ -770,8 +770,8 @@ static void output_aliases(struct module *modules, FILE *out, char *dirname) { struct module *i; struct elf_file *file; - const char *p; - unsigned long size; + struct string_table *tbl; + int j; fprintf(out, "# Aliases extracted from modules themselves.\n"); for (i = modules; i; i = i->next) { @@ -781,19 +781,20 @@ static void output_aliases(struct module *modules, FILE *out, char *dirname) filename2modname(modname, i->pathname); /* Grab from old-style .modalias section. */ - for (p = file->ops->get_aliases(file, &size); - p; - p = next_string(p, &size)) - fprintf(out, "alias %s %s\n", p, modname); - - /* Grab form new-style .modinfo section. */ - for (p = file->ops->get_modinfo(file, &size); - p; - p = next_string(p, &size)) { + tbl = file->ops->load_strings(file, ".modalias", NULL, fatal); + for (j = 0; tbl && j < tbl->cnt; j++) + fprintf(out, "alias %s %s\n", tbl->str[j], modname); + strtbl_free(tbl); + + /* Grab from new-style .modinfo section. */ + tbl = file->ops->load_strings(file, ".modinfo", NULL, fatal); + for (j = 0; tbl && j < tbl->cnt; j++) { + const char *p = tbl->str[j]; if (strstarts(p, "alias=")) fprintf(out, "alias %s %s\n", p + strlen("alias="), modname); } + strtbl_free(tbl); } } @@ -801,9 +802,9 @@ static void output_aliases_bin(struct module *modules, FILE *out, char *dirname) { struct module *i; struct elf_file *file; - const char *p; + struct string_table *tbl; + int j; char *alias; - unsigned long size; struct index_node *index; int duplicate; @@ -816,10 +817,9 @@ static void output_aliases_bin(struct module *modules, FILE *out, char *dirname) filename2modname(modname, i->pathname); /* Grab from old-style .modalias section. */ - for (p = file->ops->get_aliases(file, &size); - p; - p = next_string(p, &size)) { - alias = NOFAIL(strdup(p)); + tbl = file->ops->load_strings(file, ".modalias", NULL, fatal); + for (j = 0; tbl && j < tbl->cnt; j++) { + alias = NOFAIL(strdup(tbl->str[j])); underscores(alias); duplicate = index_insert(index, alias, modname, i->order); if (duplicate && warn_dups) @@ -827,11 +827,12 @@ static void output_aliases_bin(struct module *modules, FILE *out, char *dirname) alias, modname); free(alias); } + strtbl_free(tbl); /* Grab from new-style .modinfo section. */ - for (p = file->ops->get_modinfo(file, &size); - p; - p = next_string(p, &size)) { + tbl = file->ops->load_strings(file, ".modinfo", NULL, fatal); + for (j = 0; tbl && j < tbl->cnt; j++) { + const char *p = tbl->str[j]; if (strstarts(p, "alias=")) { alias = NOFAIL(strdup(p + strlen("alias="))); underscores(alias); @@ -842,6 +843,7 @@ static void output_aliases_bin(struct module *modules, FILE *out, char *dirname) free(alias); } } + strtbl_free(tbl); } index_write(index, out); @@ -2,6 +2,7 @@ #define MODINITTOOLS_MODULEOPS_H #include <stdio.h> #include <stdint.h> +#include "logging.h" /* All the icky stuff to do with manipulating 64 and 32-bit modules belongs here. */ @@ -71,6 +72,8 @@ struct module_ops { void *(*load_section)(struct elf_file *module, const char *secname, unsigned long *secsize); + struct string_table *(*load_strings)(struct elf_file *module, + const char *secname, struct string_table *tbl, errfn_t error); struct string_table *(*load_symbols)(struct elf_file *module); struct string_table *(*load_dep_syms)(const char *pathname, struct elf_file *module, struct string_table **types); diff --git a/elfops_core.c b/elfops_core.c index 39fd4c3..c5e84ba 100644 --- a/elfops_core.c +++ b/elfops_core.c @@ -36,6 +36,8 @@ static void *PERBIT(get_section)(struct elf_file *module, const char *secnames; unsigned int i; + *secsize = 0; + if (len <= 0 || len < sizeof(*hdr)) return NULL; @@ -65,7 +67,6 @@ static void *PERBIT(get_section)(struct elf_file *module, return data + secoffset; } } - *secsize = 0; return NULL; } @@ -79,7 +80,8 @@ static void *PERBIT(load_section)(struct elf_file *module, static struct string_table *PERBIT(load_strings)(struct elf_file *module, const char *secname, - struct string_table *tbl) + struct string_table *tbl, + errfn_t error) { unsigned long size; const char *strings; @@ -107,11 +109,11 @@ static struct string_table *PERBIT(load_symbols)(struct elf_file *module) symtbl = NULL; /* New-style: strings are in this section. */ - symtbl = PERBIT(load_strings)(module, "__ksymtab_strings", symtbl); + symtbl = PERBIT(load_strings)(module, "__ksymtab_strings", symtbl, fatal); if (symtbl) { /* GPL symbols too */ return PERBIT(load_strings)(module, "__ksymtab_strings_gpl", - symtbl); + symtbl, fatal); } /* Old-style. */ @@ -190,8 +192,9 @@ static struct string_table *PERBIT(load_dep_syms)(const char *pathname, weak = (ELFPERBIT(ST_BIND)(END(syms[i].st_info, conv)) == STB_WEAK); - names = strtbl_add(name, names); - *types = strtbl_add(weak ? weak_sym : undef_sym, *types); + names = NOFAIL(strtbl_add(name, names)); + *types = NOFAIL(strtbl_add(weak ? weak_sym : undef_sym, + *types)); } } return names; @@ -238,15 +241,7 @@ static void PERBIT(fetch_tables)(struct elf_file *module, if (!strings || !syms) return; - tables->pci_table = NULL; - tables->usb_table = NULL; - tables->ccw_table = NULL; - tables->ieee1394_table = NULL; - tables->pnp_table = NULL; - tables->pnp_card_table = NULL; - tables->input_table = NULL; - tables->serio_table = NULL; - tables->of_table = NULL; + memset(tables, 0x00, sizeof(struct module_tables)); for (i = 0; i < size / sizeof(syms[0]); i++) { char *name = strings + END(syms[i].st_name, conv); @@ -344,6 +339,7 @@ static int PERBIT(dump_modversions)(struct elf_file *module) struct module_ops PERBIT(mod_ops) = { .load_section = PERBIT(load_section), + .load_strings = PERBIT(load_strings), .load_symbols = PERBIT(load_symbols), .load_dep_syms = PERBIT(load_dep_syms), .fetch_tables = PERBIT(fetch_tables), @@ -18,6 +18,8 @@ extern void error(const char *fmt, ...); extern void warn(const char *fmt, ...); extern void info(const char *fmt, ...); +typedef void (*errfn_t)(const char *fmt, ...); + static inline void grammar(const char *cmd, const char *filename, unsigned int line) { @@ -50,9 +50,10 @@ static struct param *add_param(const char *name, struct param **list) return i; } -static void print_tag(const char *tag, const char *info, unsigned long size, +static void print_tag(const char *tag, struct string_table *tags, const char *filename, char sep) { + int j; unsigned int taglen = strlen(tag); if (streq(tag, "filename")) { @@ -60,18 +61,22 @@ static void print_tag(const char *tag, const char *info, unsigned long size, return; } - for (; info; info = next_string(info, &size)) + for (j = 0; j < tags->cnt; j++) { + const char *info = tags->str[j]; if (strncmp(info, tag, taglen) == 0 && info[taglen] == '=') printf("%s%c", info + taglen + 1, sep); + } } -static void print_all(const char *info, unsigned long size, +static void print_all(struct string_table *tags, const char *filename, char sep) { + int j; struct param *i, *params = NULL; printf("%-16s%s%c", "filename:", filename, sep); - for (; info; info = next_string(info, &size)) { + for (j = 0; j < tags->cnt; j++) { + const char *info = tags->str[j]; char *eq, *colon; /* We expect this in parm and parmtype. */ @@ -294,8 +299,7 @@ int main(int argc, char *argv[]) } for (opt = optind; opt < argc; opt++) { - void *info; - unsigned long infosize = 0; + struct string_table *tags; struct elf_file *mod; mod = grab_module(argv[opt], kernel, basedir); @@ -303,15 +307,16 @@ int main(int argc, char *argv[]) ret = 1; continue; } - info = mod->ops->get_modinfo(mod, &infosize); - if (!info) { + tags = mod->ops->load_strings(mod, ".modinfo", NULL, error); + if (!tags) { release_elf_file(mod); continue; } if (field) - print_tag(field, info, infosize, mod->pathname, sep); + print_tag(field, tags, mod->pathname, sep); else - print_all(info, infosize, mod->pathname, sep); + print_all(tags, mod->pathname, sep); + strtbl_free(tags); release_elf_file(mod); } return ret; @@ -64,8 +64,6 @@ struct module { #define MODULE_DIR "/lib/modules" #endif -typedef void (*errfn_t)(const char *fmt, ...); - static void print_usage(const char *progname) { fprintf(stderr, @@ -326,15 +324,16 @@ static void rename_module(struct elf_file *module, static void clear_magic(struct elf_file *module) { - const char *p; - unsigned long len; + struct string_table *tbl; + int j; /* Old-style: __vermagic section */ module->ops->strip_section(module, "__vermagic"); /* New-style: in .modinfo section */ - p = module->ops->get_modinfo(module, &len); - for (; p; p = next_string(p, &len)) { + tbl = module->ops->load_strings(module, ".modinfo", NULL, fatal); + for (j = 0; tbl && j < tbl->cnt; j++) { + const char *p = tbl->str[j]; if (strstarts(p, "vermagic=")) { memset((char *)p, 0, strlen(p)); return; @@ -667,23 +666,9 @@ static int insmod(struct list_head *list, module = grab_elf_file_fd(mod->filename, fd); if (!module) { - /* This is an ugly hack that maintains the logic where - * init_module() sets errno = ENOEXEC if the file is - * not an ELF object. - */ - if (errno == ENOEXEC) { - struct stat st; - optstring = add_extra_options(mod->modname, - optstring, options); - if (dry_run) - goto out; - fstat(fd, &st); - ret = init_module(NULL, st.st_size, optstring); - goto out_hack; - } - - error("Could not read '%s': %s\n", - mod->filename, strerror(errno)); + error("Could not read '%s': %s\n", mod->filename, + (errno == ENOEXEC) ? "Invalid module format" : + strerror(errno)); goto out_unlock; } if (newname) @@ -702,7 +687,6 @@ static int insmod(struct list_head *list, goto out; ret = init_module(module->data, module->len, optstring); -out_hack: if (ret != 0) { if (errno == EEXIST) { if (first_time) diff --git a/tests/test-modprobe-indexed/10alias.sh b/tests/test-modprobe-indexed/10alias.sh index bd16131..c2a2f5a 100644 --- a/tests/test-modprobe-indexed/10alias.sh +++ b/tests/test-modprobe-indexed/10alias.sh @@ -21,7 +21,8 @@ rm -f $MODULE_DIR/modules.alias rm -f $MODULE_DIR/modules.alias.bin rm -f tests/tmp/etc/modprobe.d/modprobe.conf -echo Test > $MODULE_DIR/kernel/foo.ko +cp tests/data/$BITNESS/complex/complex_a-$BITNESS.ko $MODULE_DIR/kernel/foo.ko +SIZE2=`wc -c < $MODULE_DIR/kernel/foo.ko` # Shouldn't complain if can't open modules.alias [ "`modprobe bar 2>&1`" = "FATAL: Module bar not found." ] @@ -34,12 +35,12 @@ modindex -o $MODULE_DIR/modules.alias.bin < $MODULE_DIR/modules.alias.bin.temp # Normal alias should override it. mkdir -p tests/tmp/etc/modprobe.d echo 'alias bar foo' > tests/tmp/etc/modprobe.d/modprobe.conf -[ "`modprobe foo 2>&1`" = "INIT_MODULE: 5 " ] +[ "`modprobe foo 2>&1`" = "INIT_MODULE: $SIZE2 " ] # If there's a real module, alias from modules.alias must NOT override. echo "foo alias_$BITNESS" > $MODULE_DIR/modules.alias.bin.temp modindex -o $MODULE_DIR/modules.alias.bin < $MODULE_DIR/modules.alias.bin.temp -[ "`modprobe foo 2>&1`" = "INIT_MODULE: 5 " ] +[ "`modprobe foo 2>&1`" = "INIT_MODULE: $SIZE2 " ] # If there's an install command, modules.alias must not override. echo 'install bar echo foo' > tests/tmp/etc/modprobe.d/modprobe.conf @@ -60,5 +61,5 @@ modindex -o $MODULE_DIR/modules.alias.bin < $MODULE_DIR/modules.alias.bin.temp OUT="`modprobe bar 2>&1`" [ "$OUT" = "INIT_MODULE: $SIZE option2 option1 -INIT_MODULE: 5 option1" ] || [ "$OUT" = "INIT_MODULE: 5 option1 +INIT_MODULE: $SIZE2 option1" ] || [ "$OUT" = "INIT_MODULE: $SIZE2 option1 INIT_MODULE: $SIZE option2 option1" ] diff --git a/tests/test-modprobe/10alias.sh b/tests/test-modprobe/10alias.sh index ebe2ea0..c5abf43 100755 --- a/tests/test-modprobe/10alias.sh +++ b/tests/test-modprobe/10alias.sh @@ -16,7 +16,8 @@ SIZE=`wc -c < tests/data/$BITNESS/alias/alias-$BITNESS.ko` echo "/lib/modules/$MODTEST_UNAME/kernel/alias-$BITNESS.ko:" > $MODULE_DIR/modules.dep echo "/lib/modules/$MODTEST_UNAME/kernel/foo.ko:" >> $MODULE_DIR/modules.dep -echo Test > $MODULE_DIR/kernel/foo.ko +cp tests/data/$BITNESS/complex/complex_a-$BITNESS.ko $MODULE_DIR/kernel/foo.ko +SIZE2=`wc -c < $MODULE_DIR/kernel/foo.ko` # Shouldn't complain if can't open modules.alias [ "`modprobe bar 2>&1`" = "FATAL: Module bar not found." ] @@ -28,11 +29,11 @@ echo "alias bar alias-$BITNESS" > $MODULE_DIR/modules.alias # Normal alias should override it. mkdir -p tests/tmp/etc/modprobe.d echo 'alias bar foo' > tests/tmp/etc/modprobe.d/modprobe.conf -[ "`modprobe foo 2>&1`" = "INIT_MODULE: 5 " ] +[ "`modprobe foo 2>&1`" = "INIT_MODULE: $SIZE2 " ] # If there's a real module, alias from modules.alias must NOT override. echo "alias foo alias-$BITNESS" > $MODULE_DIR/modules.alias -[ "`modprobe foo 2>&1`" = "INIT_MODULE: 5 " ] +[ "`modprobe foo 2>&1`" = "INIT_MODULE: $SIZE2 " ] # If there's an install command, modules.alias must not override. echo 'install bar echo foo' > tests/tmp/etc/modprobe.d/modprobe.conf @@ -51,5 +52,5 @@ echo "alias bar foo" >> $MODULE_DIR/modules.alias OUT="`modprobe bar 2>&1`" [ "$OUT" = "INIT_MODULE: $SIZE option2 option1 -INIT_MODULE: 5 option1" ] || [ "$OUT" = "INIT_MODULE: 5 option1 +INIT_MODULE: $SIZE2 option1" ] || [ "$OUT" = "INIT_MODULE: $SIZE2 option1 INIT_MODULE: $SIZE option2 option1" ] diff --git a/tests/test-modprobe/26blacklist.sh b/tests/test-modprobe/26blacklist.sh index 8fcff39..482ee93 100755 --- a/tests/test-modprobe/26blacklist.sh +++ b/tests/test-modprobe/26blacklist.sh @@ -15,7 +15,8 @@ SIZE=`wc -c < tests/data/$BITNESS/alias/alias-$BITNESS.ko` echo "/lib/modules/$MODTEST_UNAME/kernel/alias-$BITNESS.ko:" > $MODULE_DIR/modules.dep echo "/lib/modules/$MODTEST_UNAME/kernel/foo.ko:" >> $MODULE_DIR/modules.dep -echo Test > $MODULE_DIR/kernel/foo.ko +cp tests/data/$BITNESS/complex/complex_a-$BITNESS.ko $MODULE_DIR/kernel/foo.ko +SIZE2=`wc -c < $MODULE_DIR/kernel/foo.ko` # First, alias found in modules.alias works. echo "alias bar alias-$BITNESS" > $MODULE_DIR/modules.alias @@ -28,7 +29,7 @@ echo "blacklist alias-$BITNESS" > tests/tmp/etc/modprobe.d/modprobe.conf # Blacklist doesn't effect other aliases. echo "alias bar foo" >> $MODULE_DIR/modules.alias -[ "`modprobe bar 2>&1`" = "INIT_MODULE: 5 " ] +[ "`modprobe bar 2>&1`" = "INIT_MODULE: $SIZE2 " ] # Blacklist both. echo "blacklist foo" >> tests/tmp/etc/modprobe.d/modprobe.conf @@ -38,5 +39,5 @@ echo "blacklist foo" >> tests/tmp/etc/modprobe.d/modprobe.conf rm -f tests/tmp/etc/modprobe.d/modprobe.conf RESULT="`modprobe bar 2>&1`" [ "$RESULT" = "INIT_MODULE: $SIZE -INIT_MODULE: 5 " ] || [ "$RESULT" = "INIT_MODULE: 5 +INIT_MODULE: $SIZE2 " ] || [ "$RESULT" = "INIT_MODULE: $SIZE2 INIT_MODULE: $SIZE " ] @@ -152,7 +152,7 @@ struct string_table *strtbl_add(const char *str, struct string_table *tbl) } /* - * strtbl_destroy - string table destructor + * strtbl_free - string table destructor */ void strtbl_free(struct string_table *tbl) { @@ -17,6 +17,7 @@ char *underscores(char *string); char *my_basename(const char *path); struct string_table *strtbl_add(const char *str, struct string_table *tbl); +void strtbl_free(struct string_table *tbl); const char *next_string(const char *string, unsigned long *secsize); |