aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Robinson <andr345@gmail.com>2009-05-09 12:55:10 +0200
committerAndreas Robinson <andr345@gmail.com>2009-05-12 12:55:40 +0200
commitfff8e6472aa31c8e7034ae5615b19f8742fe484c (patch)
tree4bccd7c312cd7375fc79e41b7b2468d15930ada5
parenta29305a4a8218b5c2ef2fb88538812674c566723 (diff)
downloadmodule-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.c36
-rw-r--r--depmod.h4
-rw-r--r--moduleops.h3
-rw-r--r--moduleops_core.c26
4 files changed, 48 insertions, 21 deletions
diff --git a/depmod.c b/depmod.c
index da4ff44..a42fed5 100644
--- a/depmod.c
+++ b/depmod.c
@@ -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:
diff --git a/depmod.h b/depmod.h
index 4d92c98..089acdd 100644
--- a/depmod.h
+++ b/depmod.h
@@ -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),