/branches/dynload/uspace/lib/rtld/module.c |
---|
File deleted |
/branches/dynload/uspace/lib/rtld/include/module.h |
---|
File deleted |
/branches/dynload/uspace/lib/rtld/include/symbol.h |
---|
38,7 → 38,7 |
#include <rtld.h> |
#include <elf.h> |
elf_symbol_t *symbol_def_find(char *name, module_t *origin, module_t **m); |
elf_symbol_t *symbol_def_find(char *name, module_t **m); |
uintptr_t symbol_get_addr(elf_symbol_t *sym, module_t *m); |
#endif |
/branches/dynload/uspace/lib/rtld/include/rtld.h |
---|
36,20 → 36,20 |
#define RTLD_H_ |
#include <sys/types.h> |
#include <libadt/list.h> |
#include <dynamic.h> |
#include <module.h> |
typedef struct { |
dyn_info_t dyn; |
size_t bias; |
} module_t; |
typedef struct { |
elf_dyn_t *rtld_dynamic; |
module_t rtld; |
module_t *program; |
module_t *libc; |
/** List of all loaded modules including rtld and the program */ |
link_t modules_head; |
} runtime_env_t; |
void _rtld_main(void); |
/branches/dynload/uspace/lib/rtld/include/dynamic.h |
---|
89,9 → 89,6 |
/* Assume for now that there's at most one needed library */ |
char *needed; |
/** Pointer to the module's dynamic section */ |
elf_dyn_t *dynamic; |
} dyn_info_t; |
void dynamic_parse(elf_dyn_t *dyn_ptr, size_t bias, dyn_info_t *info); |
/branches/dynload/uspace/lib/rtld/symbol.c |
---|
103,50 → 103,23 |
return sym; /* 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) |
elf_symbol_t *symbol_def_find(char *name, module_t **m) |
{ |
module_t *m; |
elf_symbol_t *sym; |
/* FIXME: support DT_SYMBOLIC */ |
//m = origin; |
sym = def_find_in_module(name, runtime_env.program); |
if (sym != NULL) { *m = runtime_env.program; return sym; } |
/* Start in the executable program */ |
m = runtime_env.program; |
sym = def_find_in_module(name, runtime_env.libc); |
if (sym != NULL) { *m = runtime_env.libc; return sym; } |
while (true) { |
sym = def_find_in_module(name, m); |
if (sym != NULL) { |
*mod = m; |
return sym; |
} |
sym = def_find_in_module(name, &runtime_env.rtld); |
if (sym != NULL) { *m = &runtime_env.rtld; return sym; } |
if (m->n_deps < 1) break; |
/* FIXME: support branching */ |
if (m->n_deps > 1) { |
printf("error: BFS unimplemented\n"); |
exit(1); |
} |
m = m->deps[0]; |
} |
printf("Error, symbol '%s' not found anywhere\n", name); |
exit(1); |
return NULL; /* Not found */ |
printf("symbol found nowhere\n"); |
*m = NULL; |
return NULL; |
} |
uintptr_t symbol_get_addr(elf_symbol_t *sym, module_t *m) |
/branches/dynload/uspace/lib/rtld/arch/ppc32/src/reloc.c |
---|
186,8 → 186,7 |
if (sym->st_name != 0) { |
printf("rel_type: %x, rel_offset: 0x%x\n", rel_type, r_offset); |
sym_def = symbol_def_find(str_tab + sym->st_name, |
m, &dest); |
sym_def = symbol_def_find(str_tab + sym->st_name, &dest); |
printf("dest name: '%s'\n", dest->dyn.soname); |
printf("dest bias: 0x%x\n", dest->bias); |
if (sym_def) { |
/branches/dynload/uspace/lib/rtld/arch/ia32/src/reloc.c |
---|
95,8 → 95,7 |
if (sym->st_name != 0) { |
// printf("rel_type: %x, rel_offset: 0x%x\n", rel_type, r_offset); |
sym_def = symbol_def_find(str_tab + sym->st_name, |
m, &dest); |
sym_def = symbol_def_find(str_tab + sym->st_name, &dest); |
// printf("dest name: '%s'\n", dest->dyn.soname); |
// printf("dest bias: 0x%x\n", dest->bias); |
if (sym_def) { |
/branches/dynload/uspace/lib/rtld/Makefile |
---|
60,7 → 60,6 |
rtld.c \ |
elf_load.c \ |
dynamic.c \ |
module.c \ |
symbol.c |
GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES))) |
/branches/dynload/uspace/lib/rtld/rtld.c |
---|
42,11 → 42,27 |
#include <dynamic.h> |
#include <pcb.h> |
#include <elf_load.h> |
#include <module.h> |
#include <arch.h> |
runtime_env_t runtime_env; |
void module_process_relocs(module_t *m) |
{ |
if (m->dyn.plt_rel == DT_REL) { |
if (m->dyn.rel != NULL) |
rel_table_process(m, m->dyn.rel, m->dyn.rel_sz); |
/* FIXME: this seems wrong */ |
if (m->dyn.jmp_rel != NULL) |
rel_table_process(m, m->dyn.jmp_rel, m->dyn.plt_rel_sz); |
} else { /* (m->dyn.plt_rel == DT_RELA) */ |
printf("table type DT_RELA\n"); |
if (m->dyn.rela != NULL) { |
printf("non-empty\n"); |
rela_table_process(m, m->dyn.rela, m->dyn.rela_sz); |
} |
} |
} |
void _rtld_main(void) |
{ |
pcb_t *pcb; |
57,17 → 73,13 |
int rc; |
printf("Hello, world! (from rtld)\n"); |
// getchar(); |
/* |
* First we need to process dynamic sections of the two modules |
* that have been already loaded, that is, of ourselves and of |
* the executable program. |
*/ |
/* rtld_dynamic and rtld->bias were filled out by the bootstrap code */ |
rtld = &runtime_env.rtld; |
printf("Parse rtld .dynamic section at 0x%x\n", runtime_env.rtld_dynamic); |
dynamic_parse(runtime_env.rtld_dynamic, rtld->bias, &rtld->dyn); |
// getchar(); |
pcb = __pcb_get(); |
printf("Parse program .dynamic section at 0x%x\n", pcb->dynamic); |
75,33 → 87,34 |
prog.bias = 0; |
prog.dyn.soname = "[program]"; |
/* Initialize list of loaded modules */ |
list_initialize(&runtime_env.modules_head); |
list_append(&prog.modules_link, &runtime_env.modules_head); |
list_append(&rtld->modules_link, &runtime_env.modules_head); |
printf("Program requested library '%s'\n", prog.dyn.needed); |
// getchar(); |
rc = elf_load_file("/libc.so.0", 0x20000, &lib_info); |
if (rc < 0) { |
printf("failed to load library\n"); |
return; |
} |
/* Pointer to program module. Used as root of the dependency graph */ |
dynamic_parse(lib_info.dynamic, 0x20000, &lib.dyn); |
lib.bias = 0x20000; |
printf("lib.bias=0x%x\n", lib.bias); |
runtime_env.program = &prog; |
runtime_env.libc = &lib; |
/* |
* Now we can continue with loading all other modules. |
*/ |
/* Parse program's relocation tables */ |
printf("Resolve references in program\n"); |
module_process_relocs(&prog); |
printf("Load all program dependencies\n"); |
module_load_deps(&prog); |
/* Parse lib's relocation tables */ |
printf("Resolve references in library\n"); |
module_process_relocs(&lib); |
/* |
* Now relocate/link all modules together. |
*/ |
printf("lib.bias=0x%x\n", lib.bias); |
/* Process relocations in all modules */ |
printf("Relocate all modules\n"); |
modules_process_relocs(); |
/* |
* Finally, run the main program. |
*/ |
printf("Run program.. (at 0x%x)\n", (uintptr_t)pcb->entry); |
getchar(); |
pcb->entry(); |
} |
/branches/dynload/uspace/lib/rtld/dynamic.c |
---|
94,10 → 94,6 |
info->soname = info->str_tab + soname_idx; |
info->rpath = info->str_tab + rpath_idx; |
/* This will be useful for parsing dependencies later */ |
info->dynamic = dyn_ptr; |
printf("str_tab=0x%x, soname_idx=0x%x, soname=0x%x\n", |
(uintptr_t)info->soname, soname_idx, (uintptr_t)info->soname); |
printf("soname='%s'\n", info->soname); |