/branches/dynload/uspace/app/dltest/dltest.c |
---|
60,10 → 60,13 |
*/ |
} |
typedef void (*fptr_t)(void); |
int main(int argc, char *argv[]) |
{ |
void *a; |
void *s; |
fptr_t fun; |
char *lib_name; |
char *sym_name; |
71,8 → 74,8 |
// kputint(-1); |
printf("Hello from dltest!\n"); |
lib_name = "libc.so.0"; |
sym_name = "printf"; |
lib_name = "libtest.so.0"; |
sym_name = "test_func"; |
a = dlopen(lib_name, 0); |
if (a != NULL) { |
79,8 → 82,14 |
s = dlsym(a, sym_name); |
printf("symbol '%s' = 0x%lx\n", sym_name, (long) s); |
} else { |
printf("failed to dlopen() library '%s'\n"); |
printf("failed to dlopen() library '%s'\n", lib_name); |
} |
printf("Run dynamically-resolved function '%s'...\n", sym_name); |
fun = (fptr_t) s; |
(*fun)(); |
printf("OK\n"); |
return 0; |
} |
/branches/dynload/uspace/app/dload/dload.c |
---|
79,6 → 79,9 |
/* Pointer to program module. Used as root of the module graph. */ |
runtime_env->program = &prog; |
/* Work around non-existent memory space allocation. */ |
runtime_env->next_bias = 0x100000; |
/* |
* Now we can continue with loading all other modules. |
*/ |
92,7 → 95,7 |
/* Process relocations in all modules */ |
DPRINTF("Relocate all modules\n"); |
modules_process_relocs(); |
modules_process_relocs(&prog); |
/* Pass runtime evironment pointer through PCB. */ |
__pcb->rtld_runtime = (void *) runtime_env; |
/branches/dynload/uspace/lib/rtld/include/module.h |
---|
48,6 → 48,9 |
/** Number of fields in deps */ |
size_t n_deps; |
/** True iff relocations have already been processed in this module. */ |
bool relocated; |
/** Link to list of all modules in runtime environment */ |
link_t modules_link; |
62,7 → 65,7 |
module_t *module_load(char *name); |
void module_load_deps(module_t *m); |
void modules_process_relocs(void); |
void modules_process_relocs(module_t *start); |
void modules_untag(void); |
#endif |
/branches/dynload/uspace/lib/rtld/include/rtld.h |
---|
59,6 → 59,9 |
/** List of all loaded modules including rtld and the program */ |
link_t modules_head; |
/** Temporary hack to place each module at different address. */ |
uintptr_t next_bias; |
} runtime_env_t; |
extern runtime_env_t *runtime_env; |
/branches/dynload/uspace/lib/rtld/include/symbol.h |
---|
38,7 → 38,8 |
#include <rtld.h> |
#include <elf.h> |
elf_symbol_t *symbol_def_find(char *name, module_t *origin, module_t **m); |
elf_symbol_t *symbol_bfs_find(char *name, module_t *start, module_t **mod); |
elf_symbol_t *symbol_def_find(char *name, module_t *origin, module_t **mod); |
uintptr_t symbol_get_addr(elf_symbol_t *sym, module_t *m); |
#endif |
/branches/dynload/uspace/lib/rtld/module.c |
---|
54,6 → 54,10 |
void module_process_relocs(module_t *m) |
{ |
DPRINTF("module_process_relocs('%s')\n", m->dyn.soname); |
/* Do not relocate twice. */ |
if (m->relocated) return; |
if (m->dyn.plt_rel == DT_REL) { |
if (m->dyn.rel != NULL) |
rel_table_process(m, m->dyn.rel, m->dyn.rel_sz); |
67,6 → 71,8 |
rela_table_process(m, m->dyn.rela, m->dyn.rela_sz); |
} |
} |
m->relocated = true; |
} |
/** Find module structure by soname/pathname. |
131,16 → 137,21 |
strcpy(name_buf, "/lib/"); |
strcpy(name_buf + 5, name); |
/* FIXME: need to vary bias / allocate address space */ |
m->bias = 0x20000; |
/* FIXME: need to real allocation of address space */ |
m->bias = runtime_env->next_bias; |
runtime_env->next_bias += 0x100000; |
DPRINTF("filename:'%s'\n", name_buf); |
rc = elf_load_file(name_buf, m->bias, ELDF_RW, &info); |
if (rc < 0) { |
if (rc != EE_OK) { |
printf("Failed to load '%s'\n", name_buf); |
exit(1); |
} |
/* Pending relocation. */ |
m->relocated = false; |
DPRINTF("parse dynamic section\n"); |
/* Parse ELF .dynamic section. Store info to m->dyn. */ |
dynamic_parse(info.dynamic, m->bias, &m->dyn); |
207,7 → 218,14 |
} |
} |
void modules_process_relocs(void) |
/** Process relocations in modules. |
* |
* Processes relocations in @a start and all its dependencies. |
* Modules that have already been relocated are unaffected. |
* |
* @param start The module where to start from. |
*/ |
void modules_process_relocs(module_t *start) |
{ |
link_t *head = &runtime_env->modules_head; |
/branches/dynload/uspace/lib/rtld/symbol.c |
---|
70,7 → 70,7 |
elf_word bucket; |
// module_name = m->dyn.soname; |
// DPRINTF("def_find_in_module('%s', %s)\n", name, module_name); |
DPRINTF("def_find_in_module('%s', %s)\n", name, module_name); |
sym_table = m->dyn.sym_tab; |
nbucket = m->dyn.hash[0]; |
103,19 → 103,18 |
return sym; /* Found */ |
} |
/** Find the definition of a symbol. |
/** Find the definition of a symbol in a module and its deps. |
* |
* By definition in System V ABI, if module origin has the flag DT_SYMBOLIC, |
* origin is searched first. Otherwise, or if the symbol hasn't been found, |
* the module dependency graph is searched breadth-first, beginning |
* from the executable program. |
* Search the module dependency graph is breadth-first, beginning |
* from the module @a start. Thus, @start and all its dependencies |
* get searched. |
* |
* @param name Name of the symbol to search for. |
* @param origin Module in which the dependency originates. |
* @param start Module in which to start the search.. |
* @param mod (output) Will be filled with a pointer to the module |
* that contains the symbol. |
*/ |
elf_symbol_t *symbol_def_find(char *name, module_t *origin, module_t **mod) |
elf_symbol_t *symbol_bfs_find(char *name, module_t *start, module_t **mod) |
{ |
module_t *m, *dm; |
elf_symbol_t *sym, *s; |
122,21 → 121,6 |
link_t queue_head; |
size_t i; |
if (origin->dyn.symbolic) { |
/* |
* Origin module has a DT_SYMBOLIC flag. |
* Try this module first |
*/ |
s = def_find_in_module(name, origin); |
if (s != NULL) { |
/* Found */ |
*mod = origin; |
return s; |
} |
} |
/* Otherwise start in the executable program */ |
/* |
* Do a BFS using the queue_link and bfs_tag fields. |
* Vertices (modules) are tagged the moment they are inserted |
149,8 → 133,8 |
/* Insert root (the program) into the queue and tag it */ |
list_initialize(&queue_head); |
runtime_env->program->bfs_tag = true; |
list_append(&runtime_env->program->queue_link, &queue_head); |
start->bfs_tag = true; |
list_append(&start->queue_link, &queue_head); |
/* If the symbol is found, it will be stored in 'sym' */ |
sym = NULL; |
196,6 → 180,43 |
return sym; /* Symbol found */ |
} |
/** Find the definition of a symbol.. |
* |
* By definition in System V ABI, if module origin has the flag DT_SYMBOLIC, |
* origin is searched first. Otherwise, or if the symbol hasn't been found, |
* the module dependency graph is searched breadth-first, beginning |
* from the executable program. |
* |
* @param name Name of the symbol to search for. |
* @param origin Module in which the dependency originates. |
* @param mod (output) Will be filled with a pointer to the module |
* that contains the symbol. |
*/ |
elf_symbol_t *symbol_def_find(char *name, module_t *origin, module_t **mod) |
{ |
module_t *m, *dm; |
elf_symbol_t *sym, *s; |
link_t queue_head; |
size_t i; |
if (origin->dyn.symbolic) { |
/* |
* Origin module has a DT_SYMBOLIC flag. |
* Try this module first |
*/ |
s = def_find_in_module(name, origin); |
if (s != NULL) { |
/* Found */ |
*mod = origin; |
return s; |
} |
} |
/* Otherwise start in the executable program */ |
return symbol_bfs_find(name, runtime_env->program, mod); |
} |
uintptr_t symbol_get_addr(elf_symbol_t *sym, module_t *m) |
{ |
if (sym->st_shndx == SHN_ABS) { |
/branches/dynload/uspace/lib/libtest/libtest.c |
---|
34,6 → 34,7 |
* @file |
*/ |
#include <stdio.h> |
#include "libtest.h" |
static void kputint(unsigned i) |
50,8 → 51,9 |
void test_func(void) |
{ |
kputint(42); |
while(1); |
printf("Hello, this is 'test_func()' in libtest.so!\n"); |
// kputint(42); |
// while(1); |
} |
/** @} |
/branches/dynload/uspace/lib/libtest/Makefile |
---|
39,10 → 39,12 |
ARCH_SOURCES := |
CFLAGS += -I../../srv/kbd/include -I../../srv/console -Iinclude -fPIC -O0 |
LFLAGS = -shared --no-undefined -soname libtest.so.0 |
LFLAGS = \ |
-shared --no-undefined -soname libtest.so.0 \ |
-Bdynamic -I/app/dload |
# LIBS = $(LIBC_PREFIX)/libc.pic.a |
LIBS = |
LIBS = $(LIBC_PREFIX)/shared/libc.so.0 |
DEFS += -DRELEASE=\"$(RELEASE)\" |
ifdef REVISION |
/branches/dynload/uspace/lib/libc/generic/dlfcn.c |
---|
55,6 → 55,9 |
m = module_load(path); |
printf("module_load_deps(m)\n"); |
module_load_deps(m); |
/* Now relocate. */ |
printf("module_process_relocs(m)\n"); |
module_process_relocs(m); |
} else { |
printf("not NULL\n"); |
} |
64,8 → 67,6 |
/* |
* @note Symbols with NULL values are not accounted for. |
* @note Symbol search scope is not correct. Should only |
* look in @a mod and its dependencies. |
*/ |
void *dlsym(void *mod, const char *sym_name) |
{ |
73,7 → 74,7 |
module_t *sm; |
printf("dlsym(0x%lx, \"%s\")\n", (long)mod, sym_name); |
sd = symbol_def_find(sym_name, (module_t *) mod, &sm); |
sd = symbol_bfs_find(sym_name, (module_t *) mod, &sm); |
if (sd != NULL) { |
return symbol_get_addr(sd, sm); |
} |
/branches/dynload/uspace/Makefile |
---|
39,6 → 39,7 |
lib/softint \ |
lib/softfloat \ |
lib/libc/shared \ |
lib/libtest \ |
srv/ns \ |
srv/loader \ |
srv/fb \ |
/branches/dynload/boot/arch/ppc32/loader/Makefile |
---|
108,7 → 108,8 |
$(USPACEDIR)/app/bdsh/bdsh |
RD_LIBS = \ |
$(USPACEDIR)/lib/libc/shared/libc.so.0 |
$(USPACEDIR)/lib/libc/shared/libc.so.0 \ |
$(USPACEDIR)/lib/libtest/libtest.so.0 |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
COMPONENT_OBJECTS := $(addsuffix .o,$(basename $(notdir $(COMPONENTS)))) |
/branches/dynload/boot/arch/ia32/Makefile.inc |
---|
57,7 → 57,8 |
$(USPACEDIR)/app/bdsh/bdsh |
RD_LIBS = \ |
$(USPACEDIR)/lib/libc/shared/libc.so.0 |
$(USPACEDIR)/lib/libc/shared/libc.so.0 \ |
$(USPACEDIR)/lib/libtest/libtest.so.0 |
build: $(BASE)/image.iso |