diff options
author | Andreas Robinson <andr345@gmail.com> | 2009-05-09 12:55:10 +0200 |
---|---|---|
committer | Andreas Robinson <andr345@gmail.com> | 2009-05-12 12:55:40 +0200 |
commit | fff8e6472aa31c8e7034ae5615b19f8742fe484c (patch) | |
tree | 4bccd7c312cd7375fc79e41b7b2468d15930ada5 | |
parent | a29305a4a8218b5c2ef2fb88538812674c566723 (diff) | |
download | module-init-tools-fff8e6472aa31c8e7034ae5615b19f8742fe484c.tar.gz |
depmod: separate symbol lookup and dependency calculation
The new load_dep_syms() operation in moduleops returns a string table of
symbols on which a module depends. calculate_deps() is moved to depmod.
Remaining depmod callbacks in moduleops are removed.
Signed-off-by: Andreas Robinson <andr345@gmail.com>
-rw-r--r-- | depmod.c | 36 | ||||
-rw-r--r-- | depmod.h | 4 | ||||
-rw-r--r-- | moduleops.h | 3 | ||||
-rw-r--r-- | moduleops_core.c | 26 |
4 files changed, 48 insertions, 21 deletions
@@ -667,6 +667,40 @@ static struct module *sort_modules(const char *dirname, struct module *list) return tlist; } +/* Calculate the dependencies for this module */ +static void calculate_deps(struct module *module) +{ + unsigned int i; + struct string_table *symnames; + struct string_table *symtypes; + + module->num_deps = 0; + module->deps = NULL; + + symnames = module->ops->load_dep_syms(module, &symtypes); + if (!symnames || !symtypes) + return; + + for (i = 0; i < symnames->cnt; i++) { + const char *name; + struct module *owner; + int weak; + + name = symnames->str[i]; + weak = (*(symtypes->str[i]) == 'W'); + owner = find_symbol(name, module->pathname, weak); + if (owner) { + info("%s needs \"%s\": %s\n", + module->pathname, name, + owner->pathname); + add_dep(module, owner); + } + } + + free(symnames); + free(symtypes); +} + static struct module *parse_modules(struct module *list) { struct module *i; @@ -684,7 +718,7 @@ static struct module *parse_modules(struct module *list) } for (i = list; i; i = i->next) - i->ops->calculate_deps(i); + calculate_deps(i); /* Strip out modules with dependency loops. */ again: @@ -4,10 +4,6 @@ struct module; -/* Functions provided by depmod.c */ -struct module *find_symbol(const char *name, const char *modname, int weak); -void add_dep(struct module *mod, struct module *depends_on); - struct module { /* Next module in list of all modules */ diff --git a/moduleops.h b/moduleops.h index 55e2320..2624fa7 100644 --- a/moduleops.h +++ b/moduleops.h @@ -17,7 +17,8 @@ struct kernel_symbol64 { struct module_ops { struct string_table *(*load_symbols)(struct module *module); - void (*calculate_deps)(struct module *module); + struct string_table *(*load_dep_syms)(struct module *module, + struct string_table **types); void (*fetch_tables)(struct module *module); char *(*get_aliases)(struct module *module, unsigned long *size); char *(*get_modinfo)(struct module *module, unsigned long *size); diff --git a/moduleops_core.c b/moduleops_core.c index 2454199..ea9b110 100644 --- a/moduleops_core.c +++ b/moduleops_core.c @@ -73,8 +73,8 @@ static char *PERBIT(get_modinfo)(struct module *module, unsigned long *size) #define STT_REGISTER 13 /* Global register reserved to app. */ #endif -/* Calculate the dependencies for this module */ -static void PERBIT(calculate_deps)(struct module *module) +static struct string_table *PERBIT(load_dep_syms)(struct module *module, + struct string_table **types) { unsigned int i; unsigned long size; @@ -82,19 +82,20 @@ static void PERBIT(calculate_deps)(struct module *module) ElfPERBIT(Sym) *syms; ElfPERBIT(Ehdr) *hdr; int handle_register_symbols; + struct string_table *names; + + names = NULL; + *types = NULL; strings = PERBIT(load_section)(module->data, ".strtab", &size, module->conv); syms = PERBIT(load_section)(module->data, ".symtab", &size, module->conv); - module->num_deps = 0; - module->deps = NULL; - if (!strings || !syms) { warn("Couldn't find symtab and strtab in module %s\n", module->pathname); - return; + return NULL; } hdr = module->data; @@ -107,7 +108,6 @@ static void PERBIT(calculate_deps)(struct module *module) if (END(syms[i].st_shndx, module->conv) == SHN_UNDEF) { /* Look for symbol */ const char *name; - struct module *owner; int weak; name = strings + END(syms[i].st_name, module->conv); @@ -125,15 +125,11 @@ static void PERBIT(calculate_deps)(struct module *module) weak = (ELFPERBIT(ST_BIND)(END(syms[i].st_info, module->conv)) == STB_WEAK); - owner = find_symbol(name, module->pathname, weak); - if (owner) { - info("%s needs \"%s\": %s\n", - module->pathname, name, - owner->pathname); - add_dep(module, owner); - } + names = strtbl_add(name, names); + *types = strtbl_add(weak ? "W" : "U", *types); } } + return names; } static void *PERBIT(deref_sym)(ElfPERBIT(Ehdr) *hdr, @@ -239,7 +235,7 @@ static void PERBIT(fetch_tables)(struct module *module) struct module_ops PERBIT(mod_ops) = { .load_symbols = PERBIT(load_symbols), - .calculate_deps = PERBIT(calculate_deps), + .load_dep_syms = PERBIT(load_dep_syms), .fetch_tables = PERBIT(fetch_tables), .get_aliases = PERBIT(get_aliases), .get_modinfo = PERBIT(get_modinfo), |