Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3688 → Rev 3689

/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