69,20 → 69,29 |
} |
} |
|
/** Find module structure by soname. |
/** Find module structure by soname/pathname. |
* |
* Used primarily to see if a module has already been loaded. |
* Modules are compared according to their soname, i.e. possible |
* path components are ignored. |
*/ |
module_t *module_find(char *soname) |
module_t *module_find(char *name) |
{ |
link_t *head = &runtime_env.modules_head; |
|
link_t *cur; |
module_t *m; |
char *p, *soname; |
|
/* FIXME!! */ |
if (soname[0] == '.') return &runtime_env.rtld; |
|
/* |
* If name contains slashes, treat it as a pathname and |
* construct soname by chopping off the path. Otherwise |
* treat it as soname. |
*/ |
p = strrchr(name, '/'); |
soname = p ? (p + 1) : name; |
|
/* Traverse list of all modules. Not extremely fast, but simple */ |
for (cur = head->next; cur != head; cur = cur->next) { |
m = list_get_instance(cur, module_t, modules_link); |
if (strcmp(m->dyn.soname, soname) == 0) { |
97,9 → 106,9 |
|
/** Load a module. |
* |
* Currently this trivially tries to load '/<soname>'. |
* Currently this trivially tries to load '/<name>'. |
*/ |
module_t *module_load(char *soname) |
module_t *module_load(char *name) |
{ |
elf_info_t info; |
char name_buf[NAME_BUF_SIZE]; |
112,9 → 121,7 |
exit(1); |
} |
|
printf("Requested load of module '%s'\n", soname); |
|
if (strlen(soname) > NAME_BUF_SIZE - 2) { |
if (strlen(name) > NAME_BUF_SIZE - 2) { |
printf("soname too long. increase NAME_BUF_SIZE\n"); |
exit(1); |
} |
121,7 → 128,7 |
|
/* Prepend soname with slash */ |
name_buf[0] = '/'; |
strcpy(name_buf + 1, soname); |
strcpy(name_buf + 1, name); |
|
/* FIXME: need to vary bias / allocate address space */ |
m->bias = 0x20000; |
136,7 → 143,6 |
printf("parse dynamic section\n"); |
/* Parse ELF .dynamic section. Store info to m->dyn. */ |
dynamic_parse(info.dynamic, m->bias, &m->dyn); |
printf("...\n"); |
|
/* Insert into the list of loaded modules */ |
list_append(&m->modules_link, &runtime_env.modules_head); |
149,7 → 155,7 |
void module_load_deps(module_t *m) |
{ |
elf_dyn_t *dp; |
char *dep_soname; |
char *dep_name; |
module_t *dm; |
size_t n, i; |
|
181,12 → 187,12 |
|
while (dp->d_tag != DT_NULL) { |
if (dp->d_tag == DT_NEEDED) { |
dep_soname = m->dyn.str_tab + dp->d_un.d_val; |
printf("needed:'%s'\n", dep_soname); |
dep_name = m->dyn.str_tab + dp->d_un.d_val; |
|
dm = module_find(dep_soname); |
printf("%s needs %s\n", m->dyn.soname, dep_name); |
dm = module_find(dep_name); |
if (!dm) { |
dm = module_load(dep_soname); |
dm = module_load(dep_name); |
module_load_deps(dm); |
} |
|
214,5 → 220,20 |
} |
} |
|
/** Clear BFS tags of all modules. |
*/ |
void modules_untag(void) |
{ |
link_t *head = &runtime_env.modules_head; |
|
link_t *cur; |
module_t *m; |
|
for (cur = head->next; cur != head; cur = cur->next) { |
m = list_get_instance(cur, module_t, modules_link); |
m->bfs_tag = false; |
} |
} |
|
/** @} |
*/ |